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
  • 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.

  • 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.

llvm::ReplaceInstWithValue

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 ()
  • How to duplicate a function?

    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

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

ConstantInt

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

ConcreteOperator

Instruction::SDiv, Instruction::UDiv

Operator

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>()

getAnalysis from ModulePass


LLVM LoopUnrollPass

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);

results matching ""

    No results matching ""