blob: 9c395a9c1f65401845834332948d7c1c30c19569 [file] [log] [blame]
Chris Lattnercf3056d2003-10-13 03:32:08 +00001//===-- EmitFunctions.cpp - interface to insert instrumentation -----------===//
John Criswellb576c942003-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 Shuklae0b51422002-07-16 18:58:08 +00009//
10// This inserts a global constant table with function pointers all along
11//
12//===----------------------------------------------------------------------===//
13
Anand Shuklae0b51422002-07-16 18:58:08 +000014#include "llvm/Constants.h"
15#include "llvm/DerivedTypes.h"
Anand Shuklae0b51422002-07-16 18:58:08 +000016#include "llvm/Module.h"
Chris Lattnerc56d2392003-01-14 22:39:29 +000017#include "llvm/Pass.h"
Anand Shuklaa235e142003-07-18 20:55:26 +000018#include "llvm/Support/CFG.h"
19
20enum Color{
21 WHITE,
22 GREY,
23 BLACK
24};
Anand Shuklae0b51422002-07-16 18:58:08 +000025
Chris Lattnerf6293092002-07-23 18:06:35 +000026namespace {
27 struct EmitFunctionTable : public Pass {
28 bool run(Module &M);
29 };
30
Chris Lattnera6275cc2002-07-26 21:12:46 +000031 RegisterOpt<EmitFunctionTable> X("emitfuncs", "Emit a Function Table");
Chris Lattnerf6293092002-07-23 18:06:35 +000032}
Anand Shuklae0b51422002-07-16 18:58:08 +000033
Anand Shuklaa235e142003-07-18 20:55:26 +000034char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){
35 color[node] = GREY;
36
Chris Lattner23ed9c12003-09-24 22:07:33 +000037 for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){
Anand Shuklaa235e142003-07-18 20:55:26 +000038
39 BasicBlock *BB = *vl;
40
41 if(color[BB]!=GREY && color[BB]!=BLACK){
42 if(!doDFS(BB, color)){
43 return 0;
44 }
45 }
46
47 //if has backedge
48 else if(color[BB]==GREY)
49 return 0;
50
51 }
52
53 color[node] = BLACK;
54 return 1;
55}
56
57char hasBackEdge(Function *F){
58 std::map<BasicBlock *, Color > color;
59 return doDFS(F->begin(), color);
60}
61
Anand Shuklae0b51422002-07-16 18:58:08 +000062// Per Module pass for inserting function table
63bool EmitFunctionTable::run(Module &M){
Chris Lattnerde579f12003-05-22 22:00:07 +000064 std::vector<const Type*> vType;
Anand Shuklaa235e142003-07-18 20:55:26 +000065
Chris Lattnerde579f12003-05-22 22:00:07 +000066 std::vector<Constant *> vConsts;
Anand Shuklaa235e142003-07-18 20:55:26 +000067 std::vector<Constant *> sBCons;
68
69 unsigned int counter = 0;
Chris Lattnerde579f12003-05-22 22:00:07 +000070 for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
Anand Shuklae0b51422002-07-16 18:58:08 +000071 if (!MI->isExternal()) {
Anand Shuklae0b51422002-07-16 18:58:08 +000072 vType.push_back(MI->getType());
Anand Shuklaa235e142003-07-18 20:55:26 +000073
74 //std::cerr<<MI;
75
Chris Lattnerde579f12003-05-22 22:00:07 +000076 vConsts.push_back(ConstantPointerRef::get(MI));
Anand Shuklaa235e142003-07-18 20:55:26 +000077 sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI)));
78
Anand Shukla619754f2003-06-01 02:40:49 +000079 counter++;
Anand Shuklae0b51422002-07-16 18:58:08 +000080 }
81
82 StructType *sttype = StructType::get(vType);
83 ConstantStruct *cstruct = ConstantStruct::get(sttype, vConsts);
84
Chris Lattner4ad02e72003-04-16 20:28:45 +000085 GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true,
86 GlobalValue::ExternalLinkage,
Anand Shuklae0b51422002-07-16 18:58:08 +000087 cstruct, "llvmFunctionTable");
88 M.getGlobalList().push_back(gb);
Anand Shukla619754f2003-06-01 02:40:49 +000089
Anand Shuklaa235e142003-07-18 20:55:26 +000090 ConstantArray *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy,
91 sBCons.size()),
92 sBCons);
93
94 GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true,
95 GlobalValue::ExternalLinkage,
96 constArray, "llvmSimpleFunction");
97
98 M.getGlobalList().push_back(funcArray);
99
Chris Lattnerfa9ee732003-06-04 20:08:47 +0000100 ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter);
Anand Shukla619754f2003-06-01 02:40:49 +0000101 GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true,
102 GlobalValue::ExternalLinkage,
103 cnst, "llvmFunctionCount");
104 M.getGlobalList().push_back(fnCount);
Anand Shuklae0b51422002-07-16 18:58:08 +0000105 return true; // Always modifies program
106}