blob: a49129399d2b0073d83057415fe66b3d59a9f4d9 [file] [log] [blame]
Chris Lattnercf3056d2003-10-13 03:32:08 +00001//===-- EmitFunctions.cpp - interface to insert instrumentation -----------===//
Misha Brukmanfd939082005-04-21 23:48:37 +00002//
John Criswellb576c942003-10-20 19:43:21 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukmanfd939082005-04-21 23:48:37 +00007//
John Criswellb576c942003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
Anand Shuklae0b51422002-07-16 18:58:08 +00009//
Brian Gaekea30dd792004-10-20 19:38:58 +000010// This inserts into the input module three new global constants containing
11// mapping information pertinent to the Reoptimizer's runtime library:
12// 1) a structure containing a pointer to each function;
13// 2) an array containing a boolean which is true iff the corresponding
14// function in 1) contains a back-edge branch suitable for the Reoptimizer's
15// first-level instrumentation;
16// 3) an integer containing the number of entries in 1) and 2).
Chris Lattnerc51733c2004-03-08 16:45:53 +000017//
18// NOTE: This pass is used by the reoptimizer only.
Anand Shuklae0b51422002-07-16 18:58:08 +000019//
20//===----------------------------------------------------------------------===//
21
Anand Shuklae0b51422002-07-16 18:58:08 +000022#include "llvm/Constants.h"
23#include "llvm/DerivedTypes.h"
Anand Shuklae0b51422002-07-16 18:58:08 +000024#include "llvm/Module.h"
Chris Lattnerc56d2392003-01-14 22:39:29 +000025#include "llvm/Pass.h"
Anand Shuklaa235e142003-07-18 20:55:26 +000026#include "llvm/Support/CFG.h"
Jeff Cohen8ca71912005-01-06 05:46:44 +000027#include "llvm/Transforms/Instrumentation.h"
Chris Lattnerc51733c2004-03-08 16:45:53 +000028using namespace llvm;
Anand Shuklae0b51422002-07-16 18:58:08 +000029
Misha Brukmanfd939082005-04-21 23:48:37 +000030namespace llvm {
Brian Gaekeccb87cd2004-09-30 20:14:07 +000031
Chris Lattnerf6293092002-07-23 18:06:35 +000032namespace {
Chris Lattnerc51733c2004-03-08 16:45:53 +000033 enum Color{
34 WHITE,
35 GREY,
36 BLACK
37 };
Misha Brukmanfd939082005-04-21 23:48:37 +000038
Chris Lattnerb12914b2004-09-20 04:48:05 +000039 struct EmitFunctionTable : public ModulePass {
40 bool runOnModule(Module &M);
Chris Lattnerf6293092002-07-23 18:06:35 +000041 };
Misha Brukmanfd939082005-04-21 23:48:37 +000042
Chris Lattnerc51733c2004-03-08 16:45:53 +000043 RegisterOpt<EmitFunctionTable>
44 X("emitfuncs", "Emit a function table for the reoptimizer");
Chris Lattnerf6293092002-07-23 18:06:35 +000045}
Anand Shuklae0b51422002-07-16 18:58:08 +000046
Chris Lattnerc51733c2004-03-08 16:45:53 +000047static char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){
Anand Shuklaa235e142003-07-18 20:55:26 +000048 color[node] = GREY;
49
Chris Lattner23ed9c12003-09-24 22:07:33 +000050 for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){
Misha Brukmanfd939082005-04-21 23:48:37 +000051
52 BasicBlock *BB = *vl;
53
Anand Shuklaa235e142003-07-18 20:55:26 +000054 if(color[BB]!=GREY && color[BB]!=BLACK){
55 if(!doDFS(BB, color)){
Jeff Cohen9d809302005-04-23 21:38:35 +000056 return 0;
Anand Shuklaa235e142003-07-18 20:55:26 +000057 }
58 }
59
60 //if has backedge
61 else if(color[BB]==GREY)
62 return 0;
63
64 }
65
66 color[node] = BLACK;
67 return 1;
68}
69
Chris Lattnerc51733c2004-03-08 16:45:53 +000070static char hasBackEdge(Function *F){
Anand Shuklaa235e142003-07-18 20:55:26 +000071 std::map<BasicBlock *, Color > color;
72 return doDFS(F->begin(), color);
73}
74
Anand Shuklae0b51422002-07-16 18:58:08 +000075// Per Module pass for inserting function table
Chris Lattnerb12914b2004-09-20 04:48:05 +000076bool EmitFunctionTable::runOnModule(Module &M){
Chris Lattnerde579f12003-05-22 22:00:07 +000077 std::vector<const Type*> vType;
Misha Brukmanfd939082005-04-21 23:48:37 +000078
Chris Lattnerde579f12003-05-22 22:00:07 +000079 std::vector<Constant *> vConsts;
Anand Shuklaa235e142003-07-18 20:55:26 +000080 std::vector<Constant *> sBCons;
81
82 unsigned int counter = 0;
Chris Lattnerde579f12003-05-22 22:00:07 +000083 for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
Anand Shuklae0b51422002-07-16 18:58:08 +000084 if (!MI->isExternal()) {
Anand Shuklae0b51422002-07-16 18:58:08 +000085 vType.push_back(MI->getType());
Misha Brukmanfd939082005-04-21 23:48:37 +000086
Anand Shuklaa235e142003-07-18 20:55:26 +000087 //std::cerr<<MI;
88
Reid Spencer518310c2004-07-18 00:44:37 +000089 vConsts.push_back(MI);
Anand Shuklaa235e142003-07-18 20:55:26 +000090 sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI)));
Misha Brukmanfd939082005-04-21 23:48:37 +000091
Anand Shukla619754f2003-06-01 02:40:49 +000092 counter++;
Anand Shuklae0b51422002-07-16 18:58:08 +000093 }
Misha Brukmanfd939082005-04-21 23:48:37 +000094
Anand Shuklae0b51422002-07-16 18:58:08 +000095 StructType *sttype = StructType::get(vType);
Chris Lattner04d1fb62004-02-15 04:07:32 +000096 Constant *cstruct = ConstantStruct::get(sttype, vConsts);
Anand Shuklae0b51422002-07-16 18:58:08 +000097
Chris Lattner4ad02e72003-04-16 20:28:45 +000098 GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true,
Misha Brukmanfd939082005-04-21 23:48:37 +000099 GlobalValue::ExternalLinkage,
Anand Shuklae0b51422002-07-16 18:58:08 +0000100 cstruct, "llvmFunctionTable");
101 M.getGlobalList().push_back(gb);
Anand Shukla619754f2003-06-01 02:40:49 +0000102
Misha Brukmanfd939082005-04-21 23:48:37 +0000103 Constant *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy,
Jeff Cohen9d809302005-04-23 21:38:35 +0000104 sBCons.size()),
105 sBCons);
Anand Shuklaa235e142003-07-18 20:55:26 +0000106
107 GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true,
Jeff Cohen9d809302005-04-23 21:38:35 +0000108 GlobalValue::ExternalLinkage,
109 constArray, "llvmSimpleFunction");
Anand Shuklaa235e142003-07-18 20:55:26 +0000110
111 M.getGlobalList().push_back(funcArray);
112
Misha Brukmanfd939082005-04-21 23:48:37 +0000113 ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter);
114 GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true,
Jeff Cohen9d809302005-04-23 21:38:35 +0000115 GlobalValue::ExternalLinkage,
116 cnst, "llvmFunctionCount");
Anand Shukla619754f2003-06-01 02:40:49 +0000117 M.getGlobalList().push_back(fnCount);
Anand Shuklae0b51422002-07-16 18:58:08 +0000118 return true; // Always modifies program
119}
Brian Gaekeccb87cd2004-09-30 20:14:07 +0000120
121ModulePass *createEmitFunctionTablePass () {
122 return new EmitFunctionTable();
123}
124
125} // end namespace llvm