mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9903 91177308-0d34-0410-b5e6-96231b3b80d8
111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
//===-- EmitFunctions.cpp - interface to insert instrumentation -----------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file was developed by the LLVM research group and is distributed under
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This inserts a global constant table with function pointers all along
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Constants.h"
|
|
#include "llvm/DerivedTypes.h"
|
|
#include "llvm/Module.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/Support/CFG.h"
|
|
|
|
namespace llvm {
|
|
|
|
enum Color{
|
|
WHITE,
|
|
GREY,
|
|
BLACK
|
|
};
|
|
|
|
namespace {
|
|
struct EmitFunctionTable : public Pass {
|
|
bool run(Module &M);
|
|
};
|
|
|
|
RegisterOpt<EmitFunctionTable> X("emitfuncs", "Emit a Function Table");
|
|
}
|
|
|
|
char doDFS(BasicBlock * node,std::map<BasicBlock *, Color > &color){
|
|
color[node] = GREY;
|
|
|
|
for(succ_iterator vl = succ_begin(node), ve = succ_end(node); vl != ve; ++vl){
|
|
|
|
BasicBlock *BB = *vl;
|
|
|
|
if(color[BB]!=GREY && color[BB]!=BLACK){
|
|
if(!doDFS(BB, color)){
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//if has backedge
|
|
else if(color[BB]==GREY)
|
|
return 0;
|
|
|
|
}
|
|
|
|
color[node] = BLACK;
|
|
return 1;
|
|
}
|
|
|
|
char hasBackEdge(Function *F){
|
|
std::map<BasicBlock *, Color > color;
|
|
return doDFS(F->begin(), color);
|
|
}
|
|
|
|
// Per Module pass for inserting function table
|
|
bool EmitFunctionTable::run(Module &M){
|
|
std::vector<const Type*> vType;
|
|
|
|
std::vector<Constant *> vConsts;
|
|
std::vector<Constant *> sBCons;
|
|
|
|
unsigned int counter = 0;
|
|
for(Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
|
|
if (!MI->isExternal()) {
|
|
vType.push_back(MI->getType());
|
|
|
|
//std::cerr<<MI;
|
|
|
|
vConsts.push_back(ConstantPointerRef::get(MI));
|
|
sBCons.push_back(ConstantInt::get(Type::SByteTy, hasBackEdge(MI)));
|
|
|
|
counter++;
|
|
}
|
|
|
|
StructType *sttype = StructType::get(vType);
|
|
ConstantStruct *cstruct = ConstantStruct::get(sttype, vConsts);
|
|
|
|
GlobalVariable *gb = new GlobalVariable(cstruct->getType(), true,
|
|
GlobalValue::ExternalLinkage,
|
|
cstruct, "llvmFunctionTable");
|
|
M.getGlobalList().push_back(gb);
|
|
|
|
ConstantArray *constArray = ConstantArray::get(ArrayType::get(Type::SByteTy,
|
|
sBCons.size()),
|
|
sBCons);
|
|
|
|
GlobalVariable *funcArray = new GlobalVariable(constArray->getType(), true,
|
|
GlobalValue::ExternalLinkage,
|
|
constArray, "llvmSimpleFunction");
|
|
|
|
M.getGlobalList().push_back(funcArray);
|
|
|
|
ConstantInt *cnst = ConstantSInt::get(Type::IntTy, counter);
|
|
GlobalVariable *fnCount = new GlobalVariable(Type::IntTy, true,
|
|
GlobalValue::ExternalLinkage,
|
|
cnst, "llvmFunctionCount");
|
|
M.getGlobalList().push_back(fnCount);
|
|
return true; // Always modifies program
|
|
}
|
|
|
|
} // End llvm namespace
|