Contents
- Tut
- Ref
- Function
- Examples
- How to iterate basic blocks, call sites, instructions
- Arguments
- Members
- Basic Block
- Members
- Instructions
- creating-and-inserting-new-instructions
- Call
- Examples
- User
- Instruction
- Creation
- Value
- Numbers
- Loop
Tut
Ref
- Great graph :)
“llvm/Transforms/Utils/BasicBlockUtils.h”
- What are .a and .so files?
.a
Archive libraries (.a) are statically linked i.e when you compile your program with -c option in gcc..so
The advantage of .so (shared object) over .a library is that they are linked during the runtime i.e. after creation of your .o file -o option in gcc.
- Fun with weak dynamic linking flat namespace
- it is also possible to use a “flat” namespace, in which case only the symbol name is considered during symbol resolution, and is searched in all loaded libraries, in the order in which they were loaded. Flat namespace can be triggered by setting the
DYLD_FORCE_FLAT_NAMESPACE
environment variable, linking the main program with -force_flat_namespace, or linking programs and libraries with the -flat_namespace argument.
- it is also possible to use a “flat” namespace, in which case only the symbol name is considered during symbol resolution, and is searched in all loaded libraries, in the order in which they were loaded. Flat namespace can be triggered by setting the
auto
<decltype(i)>
Ten Ways to Check if an Integer Is a Power Of Two in C
Function
Examples
How to iterate basic blocks, call sites, instructions (count call sites)
virtual runOnFunction(Function& F) {
for (Function::iterator b = F.begin(), be = F.end(); b != be; ++b) {
for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) {
if (CallInst* callInst = dyn_cast<CallInst>(&*i)) {
// We know we've encountered a call instruction, so we
// need to determine if it's a call to the
// function pointed to by m_func or not.
if (callInst->getCalledFunction() == targetFunc)
++callCounter;
}
}
}
}
How to iterate over basic blocks?
for (Function::iterator b = func->begin(), be = func->end(); b != be; ++b) {
BasicBlock* BB = b;
How to insert/replace insructions
Replacing an Instruction with another Value
BasicBlockUtils.h
: (“llvm/Transforms/Utils/BasicBlockUtils.h”)
ReplaceInstWithValue and ReplaceInstWithInst.
void llvm::ReplaceInstWithValue (BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Value *V)
ReplaceInstWithValue - Replace all uses of an instruction (specified by BI) with a value, then remove and delete the original instruction.
Value
:
void replaceAllUsesWith (Value *V)
Change all uses of this to point to a new Value.
Arguments
- Doc: Function class
- Function Argument Iteration
- arg_iterator arg_begin ()
- const_arg_iterator arg_begin () const
- arg_iterator arg_end ()
- const_arg_iterator arg_end () const
- iterator_range< arg_iterator > args ()
-
for (Function::arg_iterator AI=F.arg_begin(), AE=F.arg_end(),
NAI=NF->arg_begin();
AI != AE; ++AI, ++NAI) { NAI->takeName(AI); }
LLVM Tutorial 2: A More Complicated Function
Function::arg_iterator args = gcd->arg_begin();
Value* x = args++;
x->setName("x");
Value* y = args++;
y->setName("y");
Members
bool isVarArg () const
isVarArg - Return true if this function takes a variable number of arguments.
size_t arg_size () const
bool arg_empty () const
const ArgumentListType & getArgumentList () const Get the underlying elements of the Function... ArgumentListType & getArgumentList ()
Basic Block
F.size
Members
const BasicBlockListType & getBasicBlockList () const BasicBlockListType & getBasicBlockList () const BasicBlock & getEntryBlock () const BasicBlock & getEntryBlock ()
Instructions
creating-and-inserting-new-instructions
creating-and-inserting-new-instructions
BasicBlock *pb = ...;
Instruction *pi = ...;
Instruction *newInst = new Instruction(...);
pb->getInstList().insert(pi, newInst); // Inserts newInst before pi in pb
Call
finding-call-sites: a-slightly-more-complex-example
Function.getNumUses()
get you the number of times the function is explicitly called in the IR.
User
Use * getOperandList ()
const Use * getOperandList () const
Value * getOperand (unsigned i) const
void setOperand (unsigned i, Value *Val)
const Use & getOperandUse (unsigned i) const
Use & getOperandUse (unsigned i)
unsigned getNumOperands () const
llvm::User <- llvm::Operator
Instruction
unsigned getOpcode () const
getOpcode() returns a member of one of the enums like Instruction::Add
.
Creation
BinaryOperator::Creat
Example of BinaryOperator::Create
CastInst* float_conv = new SIToFPInst(int32_a, Type::getFloatTy(mod->getContext()), "conv", label_entry);
BinaryOperator* float_add = BinaryOperator::Create(Instruction::FAdd, float_conv, float_b, "add", label_entry);
ReturnInst::Create(mod->getContext(), float_add, label_entry);
Value
void replaceAllUsesWith (Value *V)
Change all uses of this to point to a new Value.
Numbers
const APInt & getValue () const
Return the constant as an APInt value reference.
unsigned getBitWidth () const
getBitWidth - Return the bitwidth of this constant.
uint64_t getZExtValue () const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate for the type of this constant.
int64_t getSExtValue () const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the type of this constant.
bool equalsInt (uint64_t V) const
A helper method that can be used to determine if the constant contained within is equal to a constant.
Operators
Instruction::SDiv, Instruction::UDiv
see graph
Instruction::Shl Instruction::AShr Instruction::LShr
Loop
get loop info
LLVM error accessing loopinfo in function pass
If you use it in a Module (pass):
LoopInfo &li = getAnalysis<LoopInfo>(F)
If you use it in a Function (pass):
LoopInfo &li = getAnalysis<LoopInfo>()
You need to implement getAnalysisUsage() in a pass to set some prerequisites for the analysisusage to make it work
void getAnalysisUsage(AnalysisUsage &AU) const override {
00984 AU.addRequired<AssumptionCacheTracker>();
00985 AU.addRequired<DominatorTreeWrapperPass>();
00986 AU.addRequired<LoopInfoWrapperPass>();
00987 AU.addPreserved<LoopInfoWrapperPass>();
00988 AU.addRequiredID(LoopSimplifyID);
00989 AU.addPreservedID(LoopSimplifyID);
00990 AU.addRequiredID(LCSSAID);
00991 AU.addPreservedID(LCSSAID);
00992 AU.addRequired<ScalarEvolutionWrapperPass>();
00993 AU.addPreserved<ScalarEvolutionWrapperPass>();
00994 AU.addRequired<TargetTransformInfoWrapperPass>();
00995 // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
00996 // If loop unroll does not preserve dom info then LCSSA pass on next
00997 // loop will receive invalid dom info.
00998 // For now, recreate dom info, if loop is unrolled.
00999 AU.addPreserved<DominatorTreeWrapperPass>();
01000 AU.addPreserved<GlobalsAAWrapperPass>();
01001 }
LLVM LoopInfo in FunctionPass doesn't compile
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "iostream"
#include "llvm/Pass.h"
#include "llvm/IR/InstIterator.h"
#include <llvm/IR/Instructions.h>
#include <llvm/Analysis/LoopInfo.h>
using namespace llvm;
namespace {
struct CFG : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
CFG() : FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<LoopInfoWrapperPass>();
}
bool runOnFunction(Function &F) override {
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
errs().write_escaped(F.getName());
errs() << " : ";
for( Function::iterator b = F.begin() , be = F.end(); b != be; ++b){
errs() << "\n\t BB : ";
bool isLoop = LI.getLoopFor(b);
if(isLoop){
errs() << "loop{";
}
for(BasicBlock::iterator i = b->begin() , ie = b->end(); i!=ie; ++i){
if( isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){
errs() << cast<CallInst>(&(*i))->getCalledFunction()->getName() << "\t";
}
}
if(isLoop){
errs() << "}";
}
}
errs() << '\n';
return false;
}
};
}
char CFG::ID = 0;
static RegisterPass<CFG> X("CFG", "Gen CFG",true ,true);