LLVM API Documentation
00001 //===-- EmitFunctions.cpp - interface to insert instrumentation -----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This inserts into the input module three new global constants containing 00011 // mapping information pertinent to the Reoptimizer's runtime library: 00012 // 1) a structure containing a pointer to each function; 00013 // 2) an array containing a boolean which is true iff the corresponding 00014 // function in 1) contains a back-edge branch suitable for the Reoptimizer's 00015 // first-level instrumentation; 00016 // 3) an integer containing the number of entries in 1) and 2). 00017 // 00018 // NOTE: This pass is used by the reoptimizer only. 00019 // 00020 //===----------------------------------------------------------------------===// 00021 00022 #include "llvm/Constants.h" 00023 #include "llvm/DerivedTypes.h" 00024 #include "llvm/Module.h" 00025 #include "llvm/Pass.h" 00026 #include "llvm/Support/CFG.h" 00027 #include "llvm/Transforms/Instrumentation.h" 00028 using namespace llvm; 00029 00030 namespace llvm { 00031 00032 namespace { 00033 enum Color{ 00034 WHITE, 00035 GREY, 00036 BLACK 00037 }; 00038 00039 struct EmitFunctionTable : public ModulePass { 00040 bool runOnModule(Module &M); 00041 }; 00042 00043 RegisterOpt<EmitFunctionTable> 00044 X("emitfuncs", "Emit a function table for the reoptimizer"); 00045 } 00046 00047 static char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){ 00048 color[node] = GREY; 00049 00050 for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){ 00051 00052 BasicBlock *BB = *vl; 00053 00054 if(color[BB]!=GREY && color[BB]!=BLACK){ 00055 if(!doDFS(BB, color)){ 00056 return 0; 00057 } 00058 } 00059 00060 //if has backedge 00061 else if(color[BB]==GREY) 00062 return 0; 00063 00064 } 00065 00066 color[node] = BLACK; 00067 return 1; 00068 } 00069 00070 static char hasBackEdge(Function *F){ 00071 std::map<BasicBlock *, Color > color; 00072 return doDFS(F->begin(), color); 00073 } 00074 00075 // Per Module pass for inserting function table 00076 bool EmitFunctionTable::runOnModule(Module &M){ 00077 std::vector<const Type*> vType; 00078 00079 std::vector<Constant *> vConsts; 00080 std::vector<Constant *> sBCons; 00081 00082 unsigned int counter = 0; 00083 for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) 00084 if (!MI->isExternal()) { 00085 vType.push_back(MI->getType()); 00086 00087 //std::cerr<<MI; 00088 00089 vConsts.push_back(MI); 00090 sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI))); 00091 00092 counter++; 00093 } 00094 00095 StructType *sttype = StructType::get(vType); 00096 Constant *cstruct = ConstantStruct::get(sttype, vConsts); 00097 00098 GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true, 00099 GlobalValue::ExternalLinkage, 00100 cstruct, "llvmFunctionTable"); 00101 M.getGlobalList().push_back(gb); 00102 00103 Constant *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy, 00104 sBCons.size()), 00105 sBCons); 00106 00107 GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true, 00108 GlobalValue::ExternalLinkage, 00109 constArray, "llvmSimpleFunction"); 00110 00111 M.getGlobalList().push_back(funcArray); 00112 00113 ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter); 00114 GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true, 00115 GlobalValue::ExternalLinkage, 00116 cnst, "llvmFunctionCount"); 00117 M.getGlobalList().push_back(fnCount); 00118 return true; // Always modifies program 00119 } 00120 00121 ModulePass *createEmitFunctionTablePass () { 00122 return new EmitFunctionTable(); 00123 } 00124 00125 } // end namespace llvm