blob: 27c25875468ddfe35174375bda2332a570d303cf [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//
Chris Lattnerc51733c2004-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 Shuklae0b51422002-07-16 18:58:08 +000013//
14//===----------------------------------------------------------------------===//
15
Anand Shuklae0b51422002-07-16 18:58:08 +000016#include "llvm/Constants.h"
17#include "llvm/DerivedTypes.h"
Anand Shuklae0b51422002-07-16 18:58:08 +000018#include "llvm/Module.h"
Chris Lattnerc56d2392003-01-14 22:39:29 +000019#include "llvm/Pass.h"
Anand Shuklaa235e142003-07-18 20:55:26 +000020#include "llvm/Support/CFG.h"
Chris Lattnerc51733c2004-03-08 16:45:53 +000021using namespace llvm;
Anand Shuklae0b51422002-07-16 18:58:08 +000022
Chris Lattnerf6293092002-07-23 18:06:35 +000023namespace {
Chris Lattnerc51733c2004-03-08 16:45:53 +000024 enum Color{
25 WHITE,
26 GREY,
27 BLACK
28 };
29
Chris Lattnerf6293092002-07-23 18:06:35 +000030 struct EmitFunctionTable : public Pass {
31 bool run(Module &M);
32 };
33
Chris Lattnerc51733c2004-03-08 16:45:53 +000034 RegisterOpt<EmitFunctionTable>
35 X("emitfuncs", "Emit a function table for the reoptimizer");
Chris Lattnerf6293092002-07-23 18:06:35 +000036}
Anand Shuklae0b51422002-07-16 18:58:08 +000037
Chris Lattnerc51733c2004-03-08 16:45:53 +000038static char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){
Anand Shuklaa235e142003-07-18 20:55:26 +000039 color[node] = GREY;
40
Chris Lattner23ed9c12003-09-24 22:07:33 +000041 for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){
Anand Shuklaa235e142003-07-18 20:55:26 +000042
43 BasicBlock *BB = *vl;
44
45 if(color[BB]!=GREY && color[BB]!=BLACK){
46 if(!doDFS(BB, color)){
47 return 0;
48 }
49 }
50
51 //if has backedge
52 else if(color[BB]==GREY)
53 return 0;
54
55 }
56
57 color[node] = BLACK;
58 return 1;
59}
60
Chris Lattnerc51733c2004-03-08 16:45:53 +000061static char hasBackEdge(Function *F){
Anand Shuklaa235e142003-07-18 20:55:26 +000062 std::map<BasicBlock *, Color > color;
63 return doDFS(F->begin(), color);
64}
65
Anand Shuklae0b51422002-07-16 18:58:08 +000066// Per Module pass for inserting function table
67bool EmitFunctionTable::run(Module &M){
Chris Lattnerde579f12003-05-22 22:00:07 +000068 std::vector<const Type*> vType;
Anand Shuklaa235e142003-07-18 20:55:26 +000069
Chris Lattnerde579f12003-05-22 22:00:07 +000070 std::vector<Constant *> vConsts;
Anand Shuklaa235e142003-07-18 20:55:26 +000071 std::vector<Constant *> sBCons;
72
73 unsigned int counter = 0;
Chris Lattnerde579f12003-05-22 22:00:07 +000074 for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
Anand Shuklae0b51422002-07-16 18:58:08 +000075 if (!MI->isExternal()) {
Anand Shuklae0b51422002-07-16 18:58:08 +000076 vType.push_back(MI->getType());
Anand Shuklaa235e142003-07-18 20:55:26 +000077
78 //std::cerr<<MI;
79
Chris Lattnerde579f12003-05-22 22:00:07 +000080 vConsts.push_back(ConstantPointerRef::get(MI));
Anand Shuklaa235e142003-07-18 20:55:26 +000081 sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI)));
82
Anand Shukla619754f2003-06-01 02:40:49 +000083 counter++;
Anand Shuklae0b51422002-07-16 18:58:08 +000084 }
85
86 StructType *sttype = StructType::get(vType);
Chris Lattner04d1fb62004-02-15 04:07:32 +000087 Constant *cstruct = ConstantStruct::get(sttype, vConsts);
Anand Shuklae0b51422002-07-16 18:58:08 +000088
Chris Lattner4ad02e72003-04-16 20:28:45 +000089 GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true,
90 GlobalValue::ExternalLinkage,
Anand Shuklae0b51422002-07-16 18:58:08 +000091 cstruct, "llvmFunctionTable");
92 M.getGlobalList().push_back(gb);
Anand Shukla619754f2003-06-01 02:40:49 +000093
Chris Lattner37106442004-02-15 04:05:58 +000094 Constant *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy,
Anand Shuklaa235e142003-07-18 20:55:26 +000095 sBCons.size()),
96 sBCons);
97
98 GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true,
99 GlobalValue::ExternalLinkage,
100 constArray, "llvmSimpleFunction");
101
102 M.getGlobalList().push_back(funcArray);
103
Chris Lattnerfa9ee732003-06-04 20:08:47 +0000104 ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter);
Anand Shukla619754f2003-06-01 02:40:49 +0000105 GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true,
106 GlobalValue::ExternalLinkage,
107 cnst, "llvmFunctionCount");
108 M.getGlobalList().push_back(fnCount);
Anand Shuklae0b51422002-07-16 18:58:08 +0000109 return true; // Always modifies program
110}