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 using namespace llvm; 00028 00029 namespace llvm { 00030 00031 namespace { 00032 enum Color{ 00033 WHITE, 00034 GREY, 00035 BLACK 00036 }; 00037 00038 struct EmitFunctionTable : public ModulePass { 00039 bool runOnModule(Module &M); 00040 }; 00041 00042 RegisterOpt<EmitFunctionTable> 00043 X("emitfuncs", "Emit a function table for the reoptimizer"); 00044 } 00045 00046 static char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){ 00047 color[node] = GREY; 00048 00049 for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){ 00050 00051 BasicBlock *BB = *vl; 00052 00053 if(color[BB]!=GREY && color[BB]!=BLACK){ 00054 if(!doDFS(BB, color)){ 00055 return 0; 00056 } 00057 } 00058 00059 //if has backedge 00060 else if(color[BB]==GREY) 00061 return 0; 00062 00063 } 00064 00065 color[node] = BLACK; 00066 return 1; 00067 } 00068 00069 static char hasBackEdge(Function *F){ 00070 std::map<BasicBlock *, Color > color; 00071 return doDFS(F->begin(), color); 00072 } 00073 00074 // Per Module pass for inserting function table 00075 bool EmitFunctionTable::runOnModule(Module &M){ 00076 std::vector<const Type*> vType; 00077 00078 std::vector<Constant *> vConsts; 00079 std::vector<Constant *> sBCons; 00080 00081 unsigned int counter = 0; 00082 for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) 00083 if (!MI->isExternal()) { 00084 vType.push_back(MI->getType()); 00085 00086 //std::cerr<<MI; 00087 00088 vConsts.push_back(MI); 00089 sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI))); 00090 00091 counter++; 00092 } 00093 00094 StructType *sttype = StructType::get(vType); 00095 Constant *cstruct = ConstantStruct::get(sttype, vConsts); 00096 00097 GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true, 00098 GlobalValue::ExternalLinkage, 00099 cstruct, "llvmFunctionTable"); 00100 M.getGlobalList().push_back(gb); 00101 00102 Constant *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy, 00103 sBCons.size()), 00104 sBCons); 00105 00106 GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true, 00107 GlobalValue::ExternalLinkage, 00108 constArray, "llvmSimpleFunction"); 00109 00110 M.getGlobalList().push_back(funcArray); 00111 00112 ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter); 00113 GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true, 00114 GlobalValue::ExternalLinkage, 00115 cnst, "llvmFunctionCount"); 00116 M.getGlobalList().push_back(fnCount); 00117 return true; // Always modifies program 00118 } 00119 00120 ModulePass *createEmitFunctionTablePass () { 00121 return new EmitFunctionTable(); 00122 } 00123 00124 } // end namespace llvm