blob: 7b624ad007c593a22906c335038c7a13e42c0f14 [file] [log] [blame]
Chris Lattner44d2c352003-10-13 03:32:08 +00001//===-- EmitFunctions.cpp - interface to insert instrumentation -----------===//
John Criswell482202a2003-10-20 19:43:21 +00002//
3// 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.
7//
8//===----------------------------------------------------------------------===//
Anand Shuklad5f25dc2002-07-16 18:58:08 +00009//
Chris Lattnerd91e6762004-03-08 16:45:53 +000010// This inserts a global constant table with function pointers all along.
11//
12// NOTE: This pass is used by the reoptimizer only.
Anand Shuklad5f25dc2002-07-16 18:58:08 +000013//
14//===----------------------------------------------------------------------===//
15
Anand Shuklad5f25dc2002-07-16 18:58:08 +000016#include "llvm/Constants.h"
17#include "llvm/DerivedTypes.h"
Anand Shuklad5f25dc2002-07-16 18:58:08 +000018#include "llvm/Module.h"
Chris Lattner57fd3072003-01-14 22:39:29 +000019#include "llvm/Pass.h"
Anand Shukla1db75a02003-07-18 20:55:26 +000020#include "llvm/Support/CFG.h"
Chris Lattnerd91e6762004-03-08 16:45:53 +000021using namespace llvm;
Anand Shuklad5f25dc2002-07-16 18:58:08 +000022
Brian Gaekee80d4cd2004-09-30 20:14:07 +000023namespace llvm {
24
Chris Lattnerb28b6802002-07-23 18:06:35 +000025namespace {
Chris Lattnerd91e6762004-03-08 16:45:53 +000026 enum Color{
27 WHITE,
28 GREY,
29 BLACK
30 };
31
Chris Lattner4f2cf032004-09-20 04:48:05 +000032 struct EmitFunctionTable : public ModulePass {
33 bool runOnModule(Module &M);
Chris Lattnerb28b6802002-07-23 18:06:35 +000034 };
35
Chris Lattnerd91e6762004-03-08 16:45:53 +000036 RegisterOpt<EmitFunctionTable>
37 X("emitfuncs", "Emit a function table for the reoptimizer");
Chris Lattnerb28b6802002-07-23 18:06:35 +000038}
Anand Shuklad5f25dc2002-07-16 18:58:08 +000039
Chris Lattnerd91e6762004-03-08 16:45:53 +000040static char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){
Anand Shukla1db75a02003-07-18 20:55:26 +000041 color[node] = GREY;
42
Chris Lattnere3178562003-09-24 22:07:33 +000043 for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){
Anand Shukla1db75a02003-07-18 20:55:26 +000044
45 BasicBlock *BB = *vl;
46
47 if(color[BB]!=GREY && color[BB]!=BLACK){
48 if(!doDFS(BB, color)){
49 return 0;
50 }
51 }
52
53 //if has backedge
54 else if(color[BB]==GREY)
55 return 0;
56
57 }
58
59 color[node] = BLACK;
60 return 1;
61}
62
Chris Lattnerd91e6762004-03-08 16:45:53 +000063static char hasBackEdge(Function *F){
Anand Shukla1db75a02003-07-18 20:55:26 +000064 std::map<BasicBlock *, Color > color;
65 return doDFS(F->begin(), color);
66}
67
Anand Shuklad5f25dc2002-07-16 18:58:08 +000068// Per Module pass for inserting function table
Chris Lattner4f2cf032004-09-20 04:48:05 +000069bool EmitFunctionTable::runOnModule(Module &M){
Chris Lattner8d0a71a2003-05-22 22:00:07 +000070 std::vector<const Type*> vType;
Anand Shukla1db75a02003-07-18 20:55:26 +000071
Chris Lattner8d0a71a2003-05-22 22:00:07 +000072 std::vector<Constant *> vConsts;
Anand Shukla1db75a02003-07-18 20:55:26 +000073 std::vector<Constant *> sBCons;
74
75 unsigned int counter = 0;
Chris Lattner8d0a71a2003-05-22 22:00:07 +000076 for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
Anand Shuklad5f25dc2002-07-16 18:58:08 +000077 if (!MI->isExternal()) {
Anand Shuklad5f25dc2002-07-16 18:58:08 +000078 vType.push_back(MI->getType());
Anand Shukla1db75a02003-07-18 20:55:26 +000079
80 //std::cerr<<MI;
81
Reid Spencercb3fb5d2004-07-18 00:44:37 +000082 vConsts.push_back(MI);
Anand Shukla1db75a02003-07-18 20:55:26 +000083 sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI)));
84
Anand Shukla03a21342003-06-01 02:40:49 +000085 counter++;
Anand Shuklad5f25dc2002-07-16 18:58:08 +000086 }
87
88 StructType *sttype = StructType::get(vType);
Chris Lattner37a716f2004-02-15 04:07:32 +000089 Constant *cstruct = ConstantStruct::get(sttype, vConsts);
Anand Shuklad5f25dc2002-07-16 18:58:08 +000090
Chris Lattner379a8d22003-04-16 20:28:45 +000091 GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true,
92 GlobalValue::ExternalLinkage,
Anand Shuklad5f25dc2002-07-16 18:58:08 +000093 cstruct, "llvmFunctionTable");
94 M.getGlobalList().push_back(gb);
Anand Shukla03a21342003-06-01 02:40:49 +000095
Chris Lattnerc75bf522004-02-15 04:05:58 +000096 Constant *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy,
Anand Shukla1db75a02003-07-18 20:55:26 +000097 sBCons.size()),
98 sBCons);
99
100 GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true,
101 GlobalValue::ExternalLinkage,
102 constArray, "llvmSimpleFunction");
103
104 M.getGlobalList().push_back(funcArray);
105
Chris Lattnera485efa2003-06-04 20:08:47 +0000106 ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter);
Anand Shukla03a21342003-06-01 02:40:49 +0000107 GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true,
108 GlobalValue::ExternalLinkage,
109 cnst, "llvmFunctionCount");
110 M.getGlobalList().push_back(fnCount);
Anand Shuklad5f25dc2002-07-16 18:58:08 +0000111 return true; // Always modifies program
112}
Brian Gaekee80d4cd2004-09-30 20:14:07 +0000113
114ModulePass *createEmitFunctionTablePass () {
115 return new EmitFunctionTable();
116}
117
118} // end namespace llvm