mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 21:20:37 +00:00
Change references from Method to Function
change references from MethodARgument to FunctionArgument git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1991 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b0d04726db
commit
79df7c0aaa
@ -10,7 +10,7 @@
|
|||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/iTerminators.h"
|
#include "llvm/iTerminators.h"
|
||||||
@ -135,8 +135,8 @@ static struct PerModuleInfo {
|
|||||||
|
|
||||||
} CurModule;
|
} CurModule;
|
||||||
|
|
||||||
static struct PerMethodInfo {
|
static struct PerFunctionInfo {
|
||||||
Method *CurrentMethod; // Pointer to current method being created
|
Function *CurrentFunction; // Pointer to current method being created
|
||||||
|
|
||||||
vector<ValueList> Values; // Keep track of numbered definitions
|
vector<ValueList> Values; // Keep track of numbered definitions
|
||||||
vector<ValueList> LateResolveValues;
|
vector<ValueList> LateResolveValues;
|
||||||
@ -144,30 +144,30 @@ static struct PerMethodInfo {
|
|||||||
map<ValID, PATypeHolder<Type> > LateResolveTypes;
|
map<ValID, PATypeHolder<Type> > LateResolveTypes;
|
||||||
bool isDeclare; // Is this method a forward declararation?
|
bool isDeclare; // Is this method a forward declararation?
|
||||||
|
|
||||||
inline PerMethodInfo() {
|
inline PerFunctionInfo() {
|
||||||
CurrentMethod = 0;
|
CurrentFunction = 0;
|
||||||
isDeclare = false;
|
isDeclare = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~PerMethodInfo() {}
|
inline ~PerFunctionInfo() {}
|
||||||
|
|
||||||
inline void MethodStart(Method *M) {
|
inline void FunctionStart(Function *M) {
|
||||||
CurrentMethod = M;
|
CurrentFunction = M;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodDone() {
|
void FunctionDone() {
|
||||||
// If we could not resolve some blocks at parsing time (forward branches)
|
// If we could not resolve some blocks at parsing time (forward branches)
|
||||||
// resolve the branches now...
|
// resolve the branches now...
|
||||||
ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
|
ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
|
||||||
|
|
||||||
Values.clear(); // Clear out method local definitions
|
Values.clear(); // Clear out method local definitions
|
||||||
Types.clear();
|
Types.clear();
|
||||||
CurrentMethod = 0;
|
CurrentFunction = 0;
|
||||||
isDeclare = false;
|
isDeclare = false;
|
||||||
}
|
}
|
||||||
} CurMeth; // Info for the current method...
|
} CurMeth; // Info for the current method...
|
||||||
|
|
||||||
static bool inMethodScope() { return CurMeth.CurrentMethod != 0; }
|
static bool inFunctionScope() { return CurMeth.CurrentFunction != 0; }
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -210,7 +210,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
|
|||||||
case 1: { // Is it a named definition?
|
case 1: { // Is it a named definition?
|
||||||
string Name(D.Name);
|
string Name(D.Name);
|
||||||
SymbolTable *SymTab = 0;
|
SymbolTable *SymTab = 0;
|
||||||
if (inMethodScope()) SymTab = CurMeth.CurrentMethod->getSymbolTable();
|
if (inFunctionScope()) SymTab = CurMeth.CurrentFunction->getSymbolTable();
|
||||||
Value *N = SymTab ? SymTab->lookup(Type::TypeTy, Name) : 0;
|
Value *N = SymTab ? SymTab->lookup(Type::TypeTy, Name) : 0;
|
||||||
|
|
||||||
if (N == 0) {
|
if (N == 0) {
|
||||||
@ -236,7 +236,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
|
|||||||
//
|
//
|
||||||
if (DoNotImprovise) return 0; // Do we just want a null to be returned?
|
if (DoNotImprovise) return 0; // Do we just want a null to be returned?
|
||||||
|
|
||||||
map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ?
|
map<ValID, PATypeHolder<Type> > &LateResolver = inFunctionScope() ?
|
||||||
CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
|
CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
|
||||||
|
|
||||||
map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
|
map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
|
||||||
@ -251,7 +251,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
|
|||||||
|
|
||||||
static Value *lookupInSymbolTable(const Type *Ty, const string &Name) {
|
static Value *lookupInSymbolTable(const Type *Ty, const string &Name) {
|
||||||
SymbolTable *SymTab =
|
SymbolTable *SymTab =
|
||||||
inMethodScope() ? CurMeth.CurrentMethod->getSymbolTable() : 0;
|
inFunctionScope() ? CurMeth.CurrentFunction->getSymbolTable() : 0;
|
||||||
Value *N = SymTab ? SymTab->lookup(Ty, Name) : 0;
|
Value *N = SymTab ? SymTab->lookup(Ty, Name) : 0;
|
||||||
|
|
||||||
if (N == 0) {
|
if (N == 0) {
|
||||||
@ -271,8 +271,9 @@ static Value *lookupInSymbolTable(const Type *Ty, const string &Name) {
|
|||||||
// it. Otherwise return null.
|
// it. Otherwise return null.
|
||||||
//
|
//
|
||||||
static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
|
static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
|
||||||
if (isa<MethodType>(Ty))
|
if (isa<FunctionType>(Ty))
|
||||||
ThrowException("Methods are not values and must be referenced as pointers");
|
ThrowException("Functions are not values and "
|
||||||
|
"must be referenced as pointers");
|
||||||
|
|
||||||
switch (D.Type) {
|
switch (D.Type) {
|
||||||
case ValID::NumberVal: { // Is it a numbered definition?
|
case ValID::NumberVal: { // Is it a numbered definition?
|
||||||
@ -377,7 +378,7 @@ static Value *getVal(const Type *Ty, const ValID &D) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(d != 0 && "How did we not make something?");
|
assert(d != 0 && "How did we not make something?");
|
||||||
if (inMethodScope())
|
if (inFunctionScope())
|
||||||
InsertValue(d, CurMeth.LateResolveValues);
|
InsertValue(d, CurMeth.LateResolveValues);
|
||||||
else
|
else
|
||||||
InsertValue(d, CurModule.LateResolveValues);
|
InsertValue(d, CurModule.LateResolveValues);
|
||||||
@ -417,7 +418,7 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers,
|
|||||||
V->replaceAllUsesWith(TheRealValue);
|
V->replaceAllUsesWith(TheRealValue);
|
||||||
delete V;
|
delete V;
|
||||||
} else if (FutureLateResolvers) {
|
} else if (FutureLateResolvers) {
|
||||||
// Methods have their unresolved items forwarded to the module late
|
// Functions have their unresolved items forwarded to the module late
|
||||||
// resolver table
|
// resolver table
|
||||||
InsertValue(V, *FutureLateResolvers);
|
InsertValue(V, *FutureLateResolvers);
|
||||||
} else {
|
} else {
|
||||||
@ -442,14 +443,14 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers,
|
|||||||
// refering to the number can be resolved. Do this now.
|
// refering to the number can be resolved. Do this now.
|
||||||
//
|
//
|
||||||
static void ResolveTypeTo(char *Name, const Type *ToTy) {
|
static void ResolveTypeTo(char *Name, const Type *ToTy) {
|
||||||
vector<PATypeHolder<Type> > &Types = inMethodScope() ?
|
vector<PATypeHolder<Type> > &Types = inFunctionScope() ?
|
||||||
CurMeth.Types : CurModule.Types;
|
CurMeth.Types : CurModule.Types;
|
||||||
|
|
||||||
ValID D;
|
ValID D;
|
||||||
if (Name) D = ValID::create(Name);
|
if (Name) D = ValID::create(Name);
|
||||||
else D = ValID::create((int)Types.size());
|
else D = ValID::create((int)Types.size());
|
||||||
|
|
||||||
map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ?
|
map<ValID, PATypeHolder<Type> > &LateResolver = inFunctionScope() ?
|
||||||
CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
|
CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
|
||||||
|
|
||||||
map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
|
map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
|
||||||
@ -492,8 +493,8 @@ static bool setValueName(Value *V, char *NameStr) {
|
|||||||
ThrowException("Can't assign name '" + Name +
|
ThrowException("Can't assign name '" + Name +
|
||||||
"' to a null valued instruction!");
|
"' to a null valued instruction!");
|
||||||
|
|
||||||
SymbolTable *ST = inMethodScope() ?
|
SymbolTable *ST = inFunctionScope() ?
|
||||||
CurMeth.CurrentMethod->getSymbolTableSure() :
|
CurMeth.CurrentFunction->getSymbolTableSure() :
|
||||||
CurModule.CurrentModule->getSymbolTableSure();
|
CurModule.CurrentModule->getSymbolTableSure();
|
||||||
|
|
||||||
Value *Existing = ST->lookup(V->getType(), Name);
|
Value *Existing = ST->lookup(V->getType(), Name);
|
||||||
@ -626,8 +627,8 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
|
|||||||
|
|
||||||
%union {
|
%union {
|
||||||
Module *ModuleVal;
|
Module *ModuleVal;
|
||||||
Method *MethodVal;
|
Function *FunctionVal;
|
||||||
std::pair<MethodArgument*,char*> *MethArgVal;
|
std::pair<FunctionArgument*,char*> *MethArgVal;
|
||||||
BasicBlock *BasicBlockVal;
|
BasicBlock *BasicBlockVal;
|
||||||
TerminatorInst *TermInstVal;
|
TerminatorInst *TermInstVal;
|
||||||
Instruction *InstVal;
|
Instruction *InstVal;
|
||||||
@ -637,7 +638,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
|
|||||||
PATypeHolder<Type> *TypeVal;
|
PATypeHolder<Type> *TypeVal;
|
||||||
Value *ValueVal;
|
Value *ValueVal;
|
||||||
|
|
||||||
std::list<std::pair<MethodArgument*,char*> > *MethodArgList;
|
std::list<std::pair<FunctionArgument*,char*> > *FunctionArgList;
|
||||||
std::vector<Value*> *ValueList;
|
std::vector<Value*> *ValueList;
|
||||||
std::list<PATypeHolder<Type> > *TypeList;
|
std::list<PATypeHolder<Type> > *TypeList;
|
||||||
std::list<std::pair<Value*,
|
std::list<std::pair<Value*,
|
||||||
@ -662,14 +663,14 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
|
|||||||
Instruction::OtherOps OtherOpVal;
|
Instruction::OtherOps OtherOpVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
%type <ModuleVal> Module MethodList
|
%type <ModuleVal> Module FunctionList
|
||||||
%type <MethodVal> Method MethodProto MethodHeader BasicBlockList
|
%type <FunctionVal> Function FunctionProto FunctionHeader BasicBlockList
|
||||||
%type <BasicBlockVal> BasicBlock InstructionList
|
%type <BasicBlockVal> BasicBlock InstructionList
|
||||||
%type <TermInstVal> BBTerminatorInst
|
%type <TermInstVal> BBTerminatorInst
|
||||||
%type <InstVal> Inst InstVal MemoryInst
|
%type <InstVal> Inst InstVal MemoryInst
|
||||||
%type <ConstVal> ConstVal
|
%type <ConstVal> ConstVal
|
||||||
%type <ConstVector> ConstVector
|
%type <ConstVector> ConstVector
|
||||||
%type <MethodArgList> ArgList ArgListH
|
%type <FunctionArgList> ArgList ArgListH
|
||||||
%type <MethArgVal> ArgVal
|
%type <MethArgVal> ArgVal
|
||||||
%type <PHIList> PHIList
|
%type <PHIList> PHIList
|
||||||
%type <ValueList> ValueRefList ValueRefListE // For call param lists
|
%type <ValueList> ValueRefList ValueRefListE // For call param lists
|
||||||
@ -807,14 +808,14 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference
|
|||||||
$$ = newTH<Type>(OT);
|
$$ = newTH<Type>(OT);
|
||||||
UR_OUT("New Upreference!\n");
|
UR_OUT("New Upreference!\n");
|
||||||
}
|
}
|
||||||
| UpRTypesV '(' ArgTypeListI ')' { // Method derived type?
|
| UpRTypesV '(' ArgTypeListI ')' { // Function derived type?
|
||||||
vector<const Type*> Params;
|
vector<const Type*> Params;
|
||||||
mapto($3->begin(), $3->end(), std::back_inserter(Params),
|
mapto($3->begin(), $3->end(), std::back_inserter(Params),
|
||||||
std::mem_fun_ref(&PATypeHandle<Type>::get));
|
std::mem_fun_ref(&PATypeHandle<Type>::get));
|
||||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||||
if (isVarArg) Params.pop_back();
|
if (isVarArg) Params.pop_back();
|
||||||
|
|
||||||
$$ = newTH(HandleUpRefs(MethodType::get(*$1, Params, isVarArg)));
|
$$ = newTH(HandleUpRefs(FunctionType::get(*$1, Params, isVarArg)));
|
||||||
delete $3; // Delete the argument list
|
delete $3; // Delete the argument list
|
||||||
delete $1; // Delete the old type handle
|
delete $1; // Delete the old type handle
|
||||||
}
|
}
|
||||||
@ -1049,13 +1050,13 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
|
|||||||
// If this is not a redefinition of a type...
|
// If this is not a redefinition of a type...
|
||||||
if (!$2) {
|
if (!$2) {
|
||||||
InsertType($4->get(),
|
InsertType($4->get(),
|
||||||
inMethodScope() ? CurMeth.Types : CurModule.Types);
|
inFunctionScope() ? CurMeth.Types : CurModule.Types);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete $4;
|
delete $4;
|
||||||
}
|
}
|
||||||
| ConstPool MethodProto { // Method prototypes can be in const pool
|
| ConstPool FunctionProto { // Function prototypes can be in const pool
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign OptInternal GlobalType ConstVal {
|
| ConstPool OptAssign OptInternal GlobalType ConstVal {
|
||||||
const Type *Ty = $5->getType();
|
const Type *Ty = $5->getType();
|
||||||
@ -1105,20 +1106,20 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
|
|||||||
// Module rule: Capture the result of parsing the whole file into a result
|
// Module rule: Capture the result of parsing the whole file into a result
|
||||||
// variable...
|
// variable...
|
||||||
//
|
//
|
||||||
Module : MethodList {
|
Module : FunctionList {
|
||||||
$$ = ParserResult = $1;
|
$$ = ParserResult = $1;
|
||||||
CurModule.ModuleDone();
|
CurModule.ModuleDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MethodList - A list of methods, preceeded by a constant pool.
|
// FunctionList - A list of methods, preceeded by a constant pool.
|
||||||
//
|
//
|
||||||
MethodList : MethodList Method {
|
FunctionList : FunctionList Function {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
assert($2->getParent() == 0 && "Method already in module!");
|
assert($2->getParent() == 0 && "Function already in module!");
|
||||||
$1->getMethodList().push_back($2);
|
$1->getFunctionList().push_back($2);
|
||||||
CurMeth.MethodDone();
|
CurMeth.FunctionDone();
|
||||||
}
|
}
|
||||||
| MethodList MethodProto {
|
| FunctionList FunctionProto {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| ConstPool IMPLEMENTATION {
|
| ConstPool IMPLEMENTATION {
|
||||||
@ -1129,13 +1130,13 @@ MethodList : MethodList Method {
|
|||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Rules to match Method Headers
|
// Rules to match Function Headers
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
OptVAR_ID : VAR_ID | /*empty*/ { $$ = 0; }
|
OptVAR_ID : VAR_ID | /*empty*/ { $$ = 0; }
|
||||||
|
|
||||||
ArgVal : Types OptVAR_ID {
|
ArgVal : Types OptVAR_ID {
|
||||||
$$ = new pair<MethodArgument*,char*>(new MethodArgument(*$1), $2);
|
$$ = new pair<FunctionArgument*,char*>(new FunctionArgument(*$1), $2);
|
||||||
delete $1; // Delete the type handle..
|
delete $1; // Delete the type handle..
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,14 +1146,14 @@ ArgListH : ArgVal ',' ArgListH {
|
|||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
| ArgVal {
|
| ArgVal {
|
||||||
$$ = new list<pair<MethodArgument*,char*> >();
|
$$ = new list<pair<FunctionArgument*,char*> >();
|
||||||
$$->push_front(*$1);
|
$$->push_front(*$1);
|
||||||
delete $1;
|
delete $1;
|
||||||
}
|
}
|
||||||
| DOTDOTDOT {
|
| DOTDOTDOT {
|
||||||
$$ = new list<pair<MethodArgument*, char*> >();
|
$$ = new list<pair<FunctionArgument*, char*> >();
|
||||||
$$->push_front(pair<MethodArgument*,char*>(
|
$$->push_front(pair<FunctionArgument*,char*>(
|
||||||
new MethodArgument(Type::VoidTy), 0));
|
new FunctionArgument(Type::VoidTy), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgList : ArgListH {
|
ArgList : ArgListH {
|
||||||
@ -1162,54 +1163,55 @@ ArgList : ArgListH {
|
|||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodHeaderH : OptInternal TypesV STRINGCONSTANT '(' ArgList ')' {
|
FunctionHeaderH : OptInternal TypesV STRINGCONSTANT '(' ArgList ')' {
|
||||||
UnEscapeLexed($3);
|
UnEscapeLexed($3);
|
||||||
string MethodName($3);
|
string FunctionName($3);
|
||||||
|
|
||||||
vector<const Type*> ParamTypeList;
|
vector<const Type*> ParamTypeList;
|
||||||
if ($5)
|
if ($5)
|
||||||
for (list<pair<MethodArgument*,char*> >::iterator I = $5->begin();
|
for (list<pair<FunctionArgument*,char*> >::iterator I = $5->begin();
|
||||||
I != $5->end(); ++I)
|
I != $5->end(); ++I)
|
||||||
ParamTypeList.push_back(I->first->getType());
|
ParamTypeList.push_back(I->first->getType());
|
||||||
|
|
||||||
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
|
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
|
||||||
if (isVarArg) ParamTypeList.pop_back();
|
if (isVarArg) ParamTypeList.pop_back();
|
||||||
|
|
||||||
const MethodType *MT = MethodType::get(*$2, ParamTypeList, isVarArg);
|
const FunctionType *MT = FunctionType::get(*$2, ParamTypeList, isVarArg);
|
||||||
const PointerType *PMT = PointerType::get(MT);
|
const PointerType *PMT = PointerType::get(MT);
|
||||||
delete $2;
|
delete $2;
|
||||||
|
|
||||||
Method *M = 0;
|
Function *M = 0;
|
||||||
if (SymbolTable *ST = CurModule.CurrentModule->getSymbolTable()) {
|
if (SymbolTable *ST = CurModule.CurrentModule->getSymbolTable()) {
|
||||||
if (Value *V = ST->lookup(PMT, MethodName)) { // Method already in symtab?
|
// Is the function already in symtab?
|
||||||
M = cast<Method>(V);
|
if (Value *V = ST->lookup(PMT, FunctionName)) {
|
||||||
|
M = cast<Function>(V);
|
||||||
|
|
||||||
// Yes it is. If this is the case, either we need to be a forward decl,
|
// Yes it is. If this is the case, either we need to be a forward decl,
|
||||||
// or it needs to be.
|
// or it needs to be.
|
||||||
if (!CurMeth.isDeclare && !M->isExternal())
|
if (!CurMeth.isDeclare && !M->isExternal())
|
||||||
ThrowException("Redefinition of method '" + MethodName + "'!");
|
ThrowException("Redefinition of method '" + FunctionName + "'!");
|
||||||
|
|
||||||
// If we found a preexisting method prototype, remove it from the module,
|
// If we found a preexisting method prototype, remove it from the module,
|
||||||
// so that we don't get spurious conflicts with global & local variables.
|
// so that we don't get spurious conflicts with global & local variables.
|
||||||
//
|
//
|
||||||
CurModule.CurrentModule->getMethodList().remove(M);
|
CurModule.CurrentModule->getFunctionList().remove(M);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (M == 0) { // Not already defined?
|
if (M == 0) { // Not already defined?
|
||||||
M = new Method(MT, $1, MethodName);
|
M = new Function(MT, $1, FunctionName);
|
||||||
InsertValue(M, CurModule.Values);
|
InsertValue(M, CurModule.Values);
|
||||||
CurModule.DeclareNewGlobalValue(M, ValID::create($3));
|
CurModule.DeclareNewGlobalValue(M, ValID::create($3));
|
||||||
}
|
}
|
||||||
free($3); // Free strdup'd memory!
|
free($3); // Free strdup'd memory!
|
||||||
|
|
||||||
CurMeth.MethodStart(M);
|
CurMeth.FunctionStart(M);
|
||||||
|
|
||||||
// Add all of the arguments we parsed to the method...
|
// Add all of the arguments we parsed to the method...
|
||||||
if ($5 && !CurMeth.isDeclare) { // Is null if empty...
|
if ($5 && !CurMeth.isDeclare) { // Is null if empty...
|
||||||
Method::ArgumentListType &ArgList = M->getArgumentList();
|
Function::ArgumentListType &ArgList = M->getArgumentList();
|
||||||
|
|
||||||
for (list<pair<MethodArgument*, char*> >::iterator I = $5->begin();
|
for (list<pair<FunctionArgument*, char*> >::iterator I = $5->begin();
|
||||||
I != $5->end(); ++I) {
|
I != $5->end(); ++I) {
|
||||||
if (setValueName(I->first, I->second)) { // Insert into symtab...
|
if (setValueName(I->first, I->second)) { // Insert into symtab...
|
||||||
assert(0 && "No arg redef allowed!");
|
assert(0 && "No arg redef allowed!");
|
||||||
@ -1221,29 +1223,29 @@ MethodHeaderH : OptInternal TypesV STRINGCONSTANT '(' ArgList ')' {
|
|||||||
delete $5; // We're now done with the argument list
|
delete $5; // We're now done with the argument list
|
||||||
} else if ($5) {
|
} else if ($5) {
|
||||||
// If we are a declaration, we should free the memory for the argument list!
|
// If we are a declaration, we should free the memory for the argument list!
|
||||||
for (list<pair<MethodArgument*, char*> >::iterator I = $5->begin();
|
for (list<pair<FunctionArgument*, char*> >::iterator I = $5->begin();
|
||||||
I != $5->end(); ++I)
|
I != $5->end(); ++I)
|
||||||
if (I->second) free(I->second); // Free the memory for the name...
|
if (I->second) free(I->second); // Free the memory for the name...
|
||||||
delete $5; // Free the memory for the list itself
|
delete $5; // Free the memory for the list itself
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodHeader : MethodHeaderH ConstPool BEGINTOK {
|
FunctionHeader : FunctionHeaderH ConstPool BEGINTOK {
|
||||||
$$ = CurMeth.CurrentMethod;
|
$$ = CurMeth.CurrentFunction;
|
||||||
|
|
||||||
// Resolve circular types before we parse the body of the method.
|
// Resolve circular types before we parse the body of the method.
|
||||||
ResolveTypes(CurMeth.LateResolveTypes);
|
ResolveTypes(CurMeth.LateResolveTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Method : BasicBlockList END {
|
Function : BasicBlockList END {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodProto : DECLARE { CurMeth.isDeclare = true; } MethodHeaderH {
|
FunctionProto : DECLARE { CurMeth.isDeclare = true; } FunctionHeaderH {
|
||||||
$$ = CurMeth.CurrentMethod;
|
$$ = CurMeth.CurrentFunction;
|
||||||
assert($$->getParent() == 0 && "Method already in module!");
|
assert($$->getParent() == 0 && "Function already in module!");
|
||||||
CurModule.CurrentModule->getMethodList().push_back($$);
|
CurModule.CurrentModule->getFunctionList().push_back($$);
|
||||||
CurMeth.MethodDone();
|
CurMeth.FunctionDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -1300,7 +1302,7 @@ ResolvedVal : Types ValueRef {
|
|||||||
BasicBlockList : BasicBlockList BasicBlock {
|
BasicBlockList : BasicBlockList BasicBlock {
|
||||||
($$ = $1)->getBasicBlocks().push_back($2);
|
($$ = $1)->getBasicBlocks().push_back($2);
|
||||||
}
|
}
|
||||||
| MethodHeader BasicBlock { // Do not allow methods with 0 basic blocks
|
| FunctionHeader BasicBlock { // Do not allow methods with 0 basic blocks
|
||||||
($$ = $1)->getBasicBlocks().push_back($2);
|
($$ = $1)->getBasicBlocks().push_back($2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1362,10 +1364,10 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
| INVOKE TypesV ValueRef '(' ValueRefListE ')' TO ResolvedVal
|
| INVOKE TypesV ValueRef '(' ValueRefListE ')' TO ResolvedVal
|
||||||
EXCEPT ResolvedVal {
|
EXCEPT ResolvedVal {
|
||||||
const PointerType *PMTy;
|
const PointerType *PMTy;
|
||||||
const MethodType *Ty;
|
const FunctionType *Ty;
|
||||||
|
|
||||||
if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
|
if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
|
||||||
!(Ty = dyn_cast<MethodType>(PMTy->getElementType()))) {
|
!(Ty = dyn_cast<FunctionType>(PMTy->getElementType()))) {
|
||||||
// Pull out the types of all of the arguments...
|
// Pull out the types of all of the arguments...
|
||||||
vector<const Type*> ParamTypes;
|
vector<const Type*> ParamTypes;
|
||||||
if ($5) {
|
if ($5) {
|
||||||
@ -1376,7 +1378,7 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
|
bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
|
||||||
if (isVarArg) ParamTypes.pop_back();
|
if (isVarArg) ParamTypes.pop_back();
|
||||||
|
|
||||||
Ty = MethodType::get($2->get(), ParamTypes, isVarArg);
|
Ty = FunctionType::get($2->get(), ParamTypes, isVarArg);
|
||||||
PMTy = PointerType::get(Ty);
|
PMTy = PointerType::get(Ty);
|
||||||
}
|
}
|
||||||
delete $2;
|
delete $2;
|
||||||
@ -1393,11 +1395,11 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
|||||||
if (!$5) { // Has no arguments?
|
if (!$5) { // Has no arguments?
|
||||||
$$ = new InvokeInst(V, Normal, Except, vector<Value*>());
|
$$ = new InvokeInst(V, Normal, Except, vector<Value*>());
|
||||||
} else { // Has arguments?
|
} else { // Has arguments?
|
||||||
// Loop through MethodType's arguments and ensure they are specified
|
// Loop through FunctionType's arguments and ensure they are specified
|
||||||
// correctly!
|
// correctly!
|
||||||
//
|
//
|
||||||
MethodType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
|
FunctionType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
|
||||||
MethodType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
|
FunctionType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
|
||||||
vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
|
vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
|
||||||
|
|
||||||
for (; ArgI != ArgE && I != E; ++ArgI, ++I)
|
for (; ArgI != ArgE && I != E; ++ArgI, ++I)
|
||||||
@ -1498,10 +1500,10 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
|
|||||||
}
|
}
|
||||||
| CALL TypesV ValueRef '(' ValueRefListE ')' {
|
| CALL TypesV ValueRef '(' ValueRefListE ')' {
|
||||||
const PointerType *PMTy;
|
const PointerType *PMTy;
|
||||||
const MethodType *Ty;
|
const FunctionType *Ty;
|
||||||
|
|
||||||
if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
|
if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
|
||||||
!(Ty = dyn_cast<MethodType>(PMTy->getElementType()))) {
|
!(Ty = dyn_cast<FunctionType>(PMTy->getElementType()))) {
|
||||||
// Pull out the types of all of the arguments...
|
// Pull out the types of all of the arguments...
|
||||||
vector<const Type*> ParamTypes;
|
vector<const Type*> ParamTypes;
|
||||||
if ($5) {
|
if ($5) {
|
||||||
@ -1512,7 +1514,7 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
|
|||||||
bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
|
bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
|
||||||
if (isVarArg) ParamTypes.pop_back();
|
if (isVarArg) ParamTypes.pop_back();
|
||||||
|
|
||||||
Ty = MethodType::get($2->get(), ParamTypes, isVarArg);
|
Ty = FunctionType::get($2->get(), ParamTypes, isVarArg);
|
||||||
PMTy = PointerType::get(Ty);
|
PMTy = PointerType::get(Ty);
|
||||||
}
|
}
|
||||||
delete $2;
|
delete $2;
|
||||||
@ -1523,11 +1525,11 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
|
|||||||
if (!$5) { // Has no arguments?
|
if (!$5) { // Has no arguments?
|
||||||
$$ = new CallInst(V, vector<Value*>());
|
$$ = new CallInst(V, vector<Value*>());
|
||||||
} else { // Has arguments?
|
} else { // Has arguments?
|
||||||
// Loop through MethodType's arguments and ensure they are specified
|
// Loop through FunctionType's arguments and ensure they are specified
|
||||||
// correctly!
|
// correctly!
|
||||||
//
|
//
|
||||||
MethodType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
|
FunctionType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
|
||||||
MethodType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
|
FunctionType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
|
||||||
vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
|
vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
|
||||||
|
|
||||||
for (; ArgI != ArgE && I != E; ++ArgI, ++I)
|
for (; ArgI != ArgE && I != E; ++ArgI, ++I)
|
||||||
|
@ -280,12 +280,12 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
|
|||||||
const MethodType::ParamTypes &Params = MTy->getParamTypes();
|
const MethodType::ParamTypes &Params = MTy->getParamTypes();
|
||||||
for (MethodType::ParamTypes::const_iterator It = Params.begin();
|
for (MethodType::ParamTypes::const_iterator It = Params.begin();
|
||||||
It != Params.end(); ++It) {
|
It != Params.end(); ++It) {
|
||||||
MethodArgument *MA = new MethodArgument(*It);
|
FunctionArgument *FA = new FunctionArgument(*It);
|
||||||
if (insertValue(MA, Values) == -1) {
|
if (insertValue(FA, Values) == -1) {
|
||||||
Error = "Error reading method arguments!\n";
|
Error = "Error reading method arguments!\n";
|
||||||
delete M; return failure(true);
|
delete M; return failure(true);
|
||||||
}
|
}
|
||||||
M->getArgumentList().push_back(MA);
|
M->getArgumentList().push_back(FA);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Buf < EndBuf) {
|
while (Buf < EndBuf) {
|
||||||
@ -352,7 +352,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
|
|||||||
assert(!getTypeSlot(MTy, type) && "How can meth type not exist?");
|
assert(!getTypeSlot(MTy, type) && "How can meth type not exist?");
|
||||||
getTypeSlot(PMTy, type);
|
getTypeSlot(PMTy, type);
|
||||||
|
|
||||||
C->getMethodList().push_back(M);
|
C->getFunctionList().push_back(M);
|
||||||
|
|
||||||
// Replace placeholder with the real method pointer...
|
// Replace placeholder with the real method pointer...
|
||||||
ModuleValues[type][MethSlot] = M;
|
ModuleValues[type][MethSlot] = M;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "WriterInternals.h"
|
#include "WriterInternals.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/ConstantVals.h"
|
#include "llvm/ConstantVals.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
@ -61,7 +61,7 @@ BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M)
|
|||||||
outputSymbolTable(*M->getSymbolTable());
|
outputSymbolTable(*M->getSymbolTable());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::outputConstants(bool isMethod) {
|
void BytecodeWriter::outputConstants(bool isFunction) {
|
||||||
BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out);
|
BytecodeBlock CPool(BytecodeFormat::ConstantPool, Out);
|
||||||
|
|
||||||
unsigned NumPlanes = Table.getNumPlanes();
|
unsigned NumPlanes = Table.getNumPlanes();
|
||||||
@ -70,13 +70,13 @@ void BytecodeWriter::outputConstants(bool isMethod) {
|
|||||||
if (Plane.empty()) continue; // Skip empty type planes...
|
if (Plane.empty()) continue; // Skip empty type planes...
|
||||||
|
|
||||||
unsigned ValNo = 0;
|
unsigned ValNo = 0;
|
||||||
if (isMethod) // Don't reemit module constants
|
if (isFunction) // Don't reemit module constants
|
||||||
ValNo = Table.getModuleLevel(pno);
|
ValNo = Table.getModuleLevel(pno);
|
||||||
else if (pno == Type::TypeTyID)
|
else if (pno == Type::TypeTyID)
|
||||||
ValNo = Type::FirstDerivedTyID; // Start emitting at the derived types...
|
ValNo = Type::FirstDerivedTyID; // Start emitting at the derived types...
|
||||||
|
|
||||||
// Scan through and ignore method arguments...
|
// Scan through and ignore method arguments...
|
||||||
for (; ValNo < Plane.size() && isa<MethodArgument>(Plane[ValNo]); ValNo++)
|
for (; ValNo < Plane.size() && isa<FunctionArgument>(Plane[ValNo]); ValNo++)
|
||||||
/*empty*/;
|
/*empty*/;
|
||||||
|
|
||||||
unsigned NC = ValNo; // Number of constants
|
unsigned NC = ValNo; // Number of constants
|
||||||
@ -149,8 +149,8 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
|||||||
align32(Out);
|
align32(Out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::processMethod(const Method *M) {
|
void BytecodeWriter::processMethod(const Function *M) {
|
||||||
BytecodeBlock MethodBlock(BytecodeFormat::Method, Out);
|
BytecodeBlock FunctionBlock(BytecodeFormat::Method, Out);
|
||||||
output_vbr((unsigned)M->hasInternalLinkage(), Out);
|
output_vbr((unsigned)M->hasInternalLinkage(), Out);
|
||||||
// Only output the constant pool and other goodies if needed...
|
// Only output the constant pool and other goodies if needed...
|
||||||
if (!M->isExternal()) {
|
if (!M->isExternal()) {
|
||||||
@ -175,14 +175,14 @@ void BytecodeWriter::processMethod(const Method *M) {
|
|||||||
|
|
||||||
|
|
||||||
void BytecodeWriter::processBasicBlock(const BasicBlock *BB) {
|
void BytecodeWriter::processBasicBlock(const BasicBlock *BB) {
|
||||||
BytecodeBlock MethodBlock(BytecodeFormat::BasicBlock, Out);
|
BytecodeBlock FunctionBlock(BytecodeFormat::BasicBlock, Out);
|
||||||
// Process all the instructions in the bb...
|
// Process all the instructions in the bb...
|
||||||
for_each(BB->begin(), BB->end(),
|
for_each(BB->begin(), BB->end(),
|
||||||
bind_obj(this, &BytecodeWriter::processInstruction));
|
bind_obj(this, &BytecodeWriter::processInstruction));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
|
void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
|
||||||
BytecodeBlock MethodBlock(BytecodeFormat::SymbolTable, Out);
|
BytecodeBlock FunctionBlock(BytecodeFormat::SymbolTable, Out);
|
||||||
|
|
||||||
for (SymbolTable::const_iterator TI = MST.begin(); TI != MST.end(); ++TI) {
|
for (SymbolTable::const_iterator TI = MST.begin(); TI != MST.end(); ++TI) {
|
||||||
SymbolTable::type_const_iterator I = MST.type_begin(TI->first);
|
SymbolTable::type_const_iterator I = MST.type_begin(TI->first);
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "llvm/CodeGen/InstrForest.h"
|
#include "llvm/CodeGen/InstrForest.h"
|
||||||
#include "llvm/CodeGen/MachineCodeForInstruction.h"
|
#include "llvm/CodeGen/MachineCodeForInstruction.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/iTerminators.h"
|
#include "llvm/iTerminators.h"
|
||||||
#include "llvm/iMemory.h"
|
#include "llvm/iMemory.h"
|
||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
@ -188,10 +188,10 @@ LabelNode::dumpNode(int indent) const
|
|||||||
// A forest of instruction trees, usually for a single method.
|
// A forest of instruction trees, usually for a single method.
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
InstrForest::InstrForest(Method *M)
|
InstrForest::InstrForest(Function *F)
|
||||||
{
|
{
|
||||||
for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) {
|
for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) {
|
||||||
BasicBlock *BB = *MI;
|
BasicBlock *BB = *FI;
|
||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
||||||
buildTreeForInstruction(*I);
|
buildTreeForInstruction(*I);
|
||||||
}
|
}
|
||||||
@ -302,11 +302,11 @@ InstrForest::buildTreeForInstruction(Instruction *instr)
|
|||||||
|
|
||||||
// Check latter condition here just to simplify the next IF.
|
// Check latter condition here just to simplify the next IF.
|
||||||
bool includeAddressOperand =
|
bool includeAddressOperand =
|
||||||
(isa<BasicBlock>(operand) || isa<Method>(operand))
|
(isa<BasicBlock>(operand) || isa<Function>(operand))
|
||||||
&& !instr->isTerminator();
|
&& !instr->isTerminator();
|
||||||
|
|
||||||
if (includeAddressOperand || isa<Instruction>(operand) ||
|
if (includeAddressOperand || isa<Instruction>(operand) ||
|
||||||
isa<Constant>(operand) || isa<MethodArgument>(operand) ||
|
isa<Constant>(operand) || isa<FunctionArgument>(operand) ||
|
||||||
isa<GlobalVariable>(operand))
|
isa<GlobalVariable>(operand))
|
||||||
{
|
{
|
||||||
// This operand is a data value
|
// This operand is a data value
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "llvm/Transforms/Linker.h"
|
#include "llvm/Transforms/Linker.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
@ -165,8 +165,8 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
|
|||||||
(V = ST->lookup(SGV->getType(), SGV->getName())) &&
|
(V = ST->lookup(SGV->getType(), SGV->getName())) &&
|
||||||
cast<GlobalVariable>(V)->hasExternalLinkage()) {
|
cast<GlobalVariable>(V)->hasExternalLinkage()) {
|
||||||
// The same named thing is a global variable, because the only two things
|
// The same named thing is a global variable, because the only two things
|
||||||
// that may be in a module level symbol table are Global Vars and Methods,
|
// that may be in a module level symbol table are Global Vars and
|
||||||
// and they both have distinct, nonoverlapping, possible types.
|
// Functions, and they both have distinct, nonoverlapping, possible types.
|
||||||
//
|
//
|
||||||
GlobalVariable *DGV = cast<GlobalVariable>(V);
|
GlobalVariable *DGV = cast<GlobalVariable>(V);
|
||||||
|
|
||||||
@ -231,13 +231,13 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkMethodProtos - Link the methods together between the two modules, without
|
// LinkFunctionProtos - Link the functions together between the two modules,
|
||||||
// doing method bodies... this just adds external method prototypes to the Dest
|
// without doing method bodies... this just adds external method prototypes to
|
||||||
// method...
|
// the Dest function...
|
||||||
//
|
//
|
||||||
static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
static bool LinkFunctionProtos(Module *Dest, const Module *Src,
|
||||||
map<const Value*, Value*> &ValueMap,
|
map<const Value*, Value*> &ValueMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
// We will need a module level symbol table if the src module has a module
|
// We will need a module level symbol table if the src module has a module
|
||||||
// level symbol table...
|
// level symbol table...
|
||||||
SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0;
|
SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0;
|
||||||
@ -245,7 +245,7 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
// Loop over all of the methods in the src module, mapping them over as we go
|
// Loop over all of the methods in the src module, mapping them over as we go
|
||||||
//
|
//
|
||||||
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const Method *SM = *I; // SrcMethod
|
const Function *SM = *I; // SrcFunction
|
||||||
Value *V;
|
Value *V;
|
||||||
|
|
||||||
// If the method has a name, and that name is already in use in the
|
// If the method has a name, and that name is already in use in the
|
||||||
@ -253,29 +253,29 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
//
|
//
|
||||||
if (SM->hasExternalLinkage() && SM->hasName() &&
|
if (SM->hasExternalLinkage() && SM->hasName() &&
|
||||||
(V = ST->lookup(SM->getType(), SM->getName())) &&
|
(V = ST->lookup(SM->getType(), SM->getName())) &&
|
||||||
cast<Method>(V)->hasExternalLinkage()) {
|
cast<Function>(V)->hasExternalLinkage()) {
|
||||||
// The same named thing is a Method, because the only two things
|
// The same named thing is a Function, because the only two things
|
||||||
// that may be in a module level symbol table are Global Vars and Methods,
|
// that may be in a module level symbol table are Global Vars and
|
||||||
// and they both have distinct, nonoverlapping, possible types.
|
// Functions, and they both have distinct, nonoverlapping, possible types.
|
||||||
//
|
//
|
||||||
Method *DM = cast<Method>(V); // DestMethod
|
Function *DM = cast<Function>(V); // DestFunction
|
||||||
|
|
||||||
// Check to make sure the method is not defined in both modules...
|
// Check to make sure the method is not defined in both modules...
|
||||||
if (!SM->isExternal() && !DM->isExternal())
|
if (!SM->isExternal() && !DM->isExternal())
|
||||||
return Error(Err, "Method '" +
|
return Error(Err, "Function '" +
|
||||||
SM->getMethodType()->getDescription() + "':\"" +
|
SM->getMethodType()->getDescription() + "':\"" +
|
||||||
SM->getName() + "\" - Method is already defined!");
|
SM->getName() + "\" - Function is already defined!");
|
||||||
|
|
||||||
// Otherwise, just remember this mapping...
|
// Otherwise, just remember this mapping...
|
||||||
ValueMap.insert(std::make_pair(SM, DM));
|
ValueMap.insert(std::make_pair(SM, DM));
|
||||||
} else {
|
} else {
|
||||||
// Method does not already exist, simply insert an external method
|
// Function does not already exist, simply insert an external method
|
||||||
// signature identical to SM into the dest module...
|
// signature identical to SM into the dest module...
|
||||||
Method *DM = new Method(SM->getMethodType(), SM->hasInternalLinkage(),
|
Function *DM = new Function(SM->getMethodType(), SM->hasInternalLinkage(),
|
||||||
SM->getName());
|
SM->getName());
|
||||||
|
|
||||||
// Add the method signature to the dest module...
|
// Add the method signature to the dest module...
|
||||||
Dest->getMethodList().push_back(DM);
|
Dest->getFunctionList().push_back(DM);
|
||||||
|
|
||||||
// ... and remember this mapping...
|
// ... and remember this mapping...
|
||||||
ValueMap.insert(std::make_pair(SM, DM));
|
ValueMap.insert(std::make_pair(SM, DM));
|
||||||
@ -284,24 +284,24 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkMethodBody - Copy the source method over into the dest method and fix up
|
// LinkFunctionBody - Copy the source method over into the dest method
|
||||||
// references to values. At this point we know that Dest is an external method,
|
// and fix up references to values. At this point we know that Dest
|
||||||
// and that Src is not.
|
// is an external method, and that Src is not.
|
||||||
//
|
//
|
||||||
static bool LinkMethodBody(Method *Dest, const Method *Src,
|
static bool LinkFunctionBody(Function *Dest, const Function *Src,
|
||||||
const map<const Value*, Value*> &GlobalMap,
|
const map<const Value*, Value*> &GlobalMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
assert(Src && Dest && Dest->isExternal() && !Src->isExternal());
|
assert(Src && Dest && Dest->isExternal() && !Src->isExternal());
|
||||||
map<const Value*, Value*> LocalMap; // Map for method local values
|
map<const Value*, Value*> LocalMap; // Map for method local values
|
||||||
|
|
||||||
// Go through and convert method arguments over...
|
// Go through and convert method arguments over...
|
||||||
for (Method::ArgumentListType::const_iterator
|
for (Function::ArgumentListType::const_iterator
|
||||||
I = Src->getArgumentList().begin(),
|
I = Src->getArgumentList().begin(),
|
||||||
E = Src->getArgumentList().end(); I != E; ++I) {
|
E = Src->getArgumentList().end(); I != E; ++I) {
|
||||||
const MethodArgument *SMA = *I;
|
const FunctionArgument *SMA = *I;
|
||||||
|
|
||||||
// Create the new method argument and add to the dest method...
|
// Create the new method argument and add to the dest method...
|
||||||
MethodArgument *DMA = new MethodArgument(SMA->getType(), SMA->getName());
|
FunctionArgument *DMA = new FunctionArgument(SMA->getType(),SMA->getName());
|
||||||
Dest->getArgumentList().push_back(DMA);
|
Dest->getArgumentList().push_back(DMA);
|
||||||
|
|
||||||
// Add a mapping to our local map
|
// Add a mapping to our local map
|
||||||
@ -310,7 +310,7 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
|
|
||||||
// Loop over all of the basic blocks, copying the instructions over...
|
// Loop over all of the basic blocks, copying the instructions over...
|
||||||
//
|
//
|
||||||
for (Method::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Function::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const BasicBlock *SBB = *I;
|
const BasicBlock *SBB = *I;
|
||||||
|
|
||||||
// Create new basic block and add to mapping and the Dest method...
|
// Create new basic block and add to mapping and the Dest method...
|
||||||
@ -338,7 +338,7 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
// in the Source method as operands. Loop through all of the operands of the
|
// in the Source method as operands. Loop through all of the operands of the
|
||||||
// methods and patch them up to point to the local versions...
|
// methods and patch them up to point to the local versions...
|
||||||
//
|
//
|
||||||
for (Method::iterator BI = Dest->begin(), BE = Dest->end();
|
for (Function::iterator BI = Dest->begin(), BE = Dest->end();
|
||||||
BI != BE; ++BI) {
|
BI != BE; ++BI) {
|
||||||
BasicBlock *BB = *BI;
|
BasicBlock *BB = *BI;
|
||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||||
@ -354,30 +354,30 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// LinkMethodBodies - Link in the method bodies that are defined in the source
|
// LinkFunctionBodies - Link in the method bodies that are defined in the source
|
||||||
// module into the DestModule. This consists basically of copying the method
|
// module into the DestModule. This consists basically of copying the method
|
||||||
// over and fixing up references to values.
|
// over and fixing up references to values.
|
||||||
//
|
//
|
||||||
static bool LinkMethodBodies(Module *Dest, const Module *Src,
|
static bool LinkFunctionBodies(Module *Dest, const Module *Src,
|
||||||
map<const Value*, Value*> &ValueMap,
|
map<const Value*, Value*> &ValueMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
|
|
||||||
// Loop over all of the methods in the src module, mapping them over as we go
|
// Loop over all of the methods in the src module, mapping them over as we go
|
||||||
//
|
//
|
||||||
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const Method *SM = *I; // Source Method
|
const Function *SM = *I; // Source Function
|
||||||
if (!SM->isExternal()) { // No body if method is external
|
if (!SM->isExternal()) { // No body if method is external
|
||||||
Method *DM = cast<Method>(ValueMap[SM]); // Destination method
|
Function *DM = cast<Function>(ValueMap[SM]); // Destination method
|
||||||
|
|
||||||
// DM not external SM external?
|
// DM not external SM external?
|
||||||
if (!DM->isExternal()) {
|
if (!DM->isExternal()) {
|
||||||
if (Err)
|
if (Err)
|
||||||
*Err = "Method '" + (SM->hasName() ? SM->getName() : string("")) +
|
*Err = "Function '" + (SM->hasName() ? SM->getName() : string("")) +
|
||||||
"' body multiply defined!";
|
"' body multiply defined!";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LinkMethodBody(DM, SM, ValueMap, Err)) return true;
|
if (LinkFunctionBody(DM, SM, ValueMap, Err)) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -418,13 +418,13 @@ bool LinkModules(Module *Dest, const Module *Src, string *ErrorMsg = 0) {
|
|||||||
// We do this so that when we begin processing method bodies, all of the
|
// We do this so that when we begin processing method bodies, all of the
|
||||||
// global values that may be referenced are available in our ValueMap.
|
// global values that may be referenced are available in our ValueMap.
|
||||||
//
|
//
|
||||||
if (LinkMethodProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
|
if (LinkFunctionProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
|
||||||
|
|
||||||
// Link in the method bodies that are defined in the source module into the
|
// Link in the method bodies that are defined in the source module into the
|
||||||
// DestModule. This consists basically of copying the method over and fixing
|
// DestModule. This consists basically of copying the method over and fixing
|
||||||
// up references to values.
|
// up references to values.
|
||||||
//
|
//
|
||||||
if (LinkMethodBodies(Dest, Src, ValueMap, ErrorMsg)) return true;
|
if (LinkFunctionBodies(Dest, Src, ValueMap, ErrorMsg)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "llvm/CodeGen/InstrForest.h"
|
#include "llvm/CodeGen/InstrForest.h"
|
||||||
#include "llvm/CodeGen/MachineCodeForInstruction.h"
|
#include "llvm/CodeGen/MachineCodeForInstruction.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/iTerminators.h"
|
#include "llvm/iTerminators.h"
|
||||||
#include "llvm/iMemory.h"
|
#include "llvm/iMemory.h"
|
||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
@ -188,10 +188,10 @@ LabelNode::dumpNode(int indent) const
|
|||||||
// A forest of instruction trees, usually for a single method.
|
// A forest of instruction trees, usually for a single method.
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
InstrForest::InstrForest(Method *M)
|
InstrForest::InstrForest(Function *F)
|
||||||
{
|
{
|
||||||
for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) {
|
for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) {
|
||||||
BasicBlock *BB = *MI;
|
BasicBlock *BB = *FI;
|
||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
|
||||||
buildTreeForInstruction(*I);
|
buildTreeForInstruction(*I);
|
||||||
}
|
}
|
||||||
@ -302,11 +302,11 @@ InstrForest::buildTreeForInstruction(Instruction *instr)
|
|||||||
|
|
||||||
// Check latter condition here just to simplify the next IF.
|
// Check latter condition here just to simplify the next IF.
|
||||||
bool includeAddressOperand =
|
bool includeAddressOperand =
|
||||||
(isa<BasicBlock>(operand) || isa<Method>(operand))
|
(isa<BasicBlock>(operand) || isa<Function>(operand))
|
||||||
&& !instr->isTerminator();
|
&& !instr->isTerminator();
|
||||||
|
|
||||||
if (includeAddressOperand || isa<Instruction>(operand) ||
|
if (includeAddressOperand || isa<Instruction>(operand) ||
|
||||||
isa<Constant>(operand) || isa<MethodArgument>(operand) ||
|
isa<Constant>(operand) || isa<FunctionArgument>(operand) ||
|
||||||
isa<GlobalVariable>(operand))
|
isa<GlobalVariable>(operand))
|
||||||
{
|
{
|
||||||
// This operand is a data value
|
// This operand is a data value
|
||||||
|
@ -153,7 +153,7 @@ static bool PatchUpMethodReferences(Module *M) {
|
|||||||
// used later.
|
// used later.
|
||||||
//
|
//
|
||||||
if (Methods[i]->use_size() == 0) {
|
if (Methods[i]->use_size() == 0) {
|
||||||
M->getMethodList().remove(Methods[i]);
|
M->getFunctionList().remove(Methods[i]);
|
||||||
delete Methods[i];
|
delete Methods[i];
|
||||||
Methods.erase(Methods.begin()+i);
|
Methods.erase(Methods.begin()+i);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
@ -273,7 +273,7 @@ void MutateStructTypes::processGlobals(Module *M) {
|
|||||||
Meth->setName("OLD."+Meth->getName());
|
Meth->setName("OLD."+Meth->getName());
|
||||||
|
|
||||||
// Insert the new method into the method list... to be filled in later...
|
// Insert the new method into the method list... to be filled in later...
|
||||||
M->getMethodList().push_back(NewMeth);
|
M->getFunctionList().push_back(NewMeth);
|
||||||
|
|
||||||
// Keep track of the association...
|
// Keep track of the association...
|
||||||
GlobalMap[Meth] = NewMeth;
|
GlobalMap[Meth] = NewMeth;
|
||||||
@ -320,7 +320,7 @@ void MutateStructTypes::removeDeadGlobals(Module *M) {
|
|||||||
#endif
|
#endif
|
||||||
for(Module::iterator I = M->begin(); I != M->end();) {
|
for(Module::iterator I = M->begin(); I != M->end();) {
|
||||||
if (GlobalMap.find(*I) != GlobalMap.end())
|
if (GlobalMap.find(*I) != GlobalMap.end())
|
||||||
delete M->getMethodList().remove(I);
|
delete M->getFunctionList().remove(I);
|
||||||
else
|
else
|
||||||
++I;
|
++I;
|
||||||
}
|
}
|
||||||
@ -341,9 +341,9 @@ void MutateStructTypes::transformMethod(Method *m) {
|
|||||||
|
|
||||||
// Okay, first order of business, create the arguments...
|
// Okay, first order of business, create the arguments...
|
||||||
for (unsigned i = 0; i < M->getArgumentList().size(); ++i) {
|
for (unsigned i = 0; i < M->getArgumentList().size(); ++i) {
|
||||||
const MethodArgument *OMA = M->getArgumentList()[i];
|
const FunctionArgument *OMA = M->getArgumentList()[i];
|
||||||
MethodArgument *NMA = new MethodArgument(ConvertType(OMA->getType()),
|
FunctionArgument *NMA = new FunctionArgument(ConvertType(OMA->getType()),
|
||||||
OMA->getName());
|
OMA->getName());
|
||||||
NewMeth->getArgumentList().push_back(NMA);
|
NewMeth->getArgumentList().push_back(NMA);
|
||||||
LocalValueMap[OMA] = NMA; // Keep track of value mapping
|
LocalValueMap[OMA] = NMA; // Keep track of value mapping
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "llvm/iMemory.h"
|
#include "llvm/iMemory.h"
|
||||||
#include "llvm/iTerminators.h"
|
#include "llvm/iTerminators.h"
|
||||||
#include "llvm/iOther.h"
|
#include "llvm/iOther.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
@ -24,12 +24,12 @@ using std::string;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class InsertTraceCode : public MethodPass {
|
class InsertTraceCode : public MethodPass {
|
||||||
bool TraceBasicBlockExits, TraceMethodExits;
|
bool TraceBasicBlockExits, TraceFunctionExits;
|
||||||
Method *PrintfMeth;
|
Function *PrintfFunc;
|
||||||
public:
|
public:
|
||||||
InsertTraceCode(bool traceBasicBlockExits, bool traceMethodExits)
|
InsertTraceCode(bool traceBasicBlockExits, bool traceFunctionExits)
|
||||||
: TraceBasicBlockExits(traceBasicBlockExits),
|
: TraceBasicBlockExits(traceBasicBlockExits),
|
||||||
TraceMethodExits(traceMethodExits) {}
|
TraceFunctionExits(traceFunctionExits) {}
|
||||||
|
|
||||||
// Add a prototype for printf if it is not already in the program.
|
// Add a prototype for printf if it is not already in the program.
|
||||||
//
|
//
|
||||||
@ -39,15 +39,15 @@ namespace {
|
|||||||
// Function InsertCodeToTraceValues
|
// Function InsertCodeToTraceValues
|
||||||
//
|
//
|
||||||
// Inserts tracing code for all live values at basic block and/or method
|
// Inserts tracing code for all live values at basic block and/or method
|
||||||
// exits as specified by `traceBasicBlockExits' and `traceMethodExits'.
|
// exits as specified by `traceBasicBlockExits' and `traceFunctionExits'.
|
||||||
//
|
//
|
||||||
static bool doit(Method *M, bool traceBasicBlockExits,
|
static bool doit(Function *M, bool traceBasicBlockExits,
|
||||||
bool traceMethodExits, Method *Printf);
|
bool traceFunctionExits, Function *Printf);
|
||||||
|
|
||||||
// runOnMethod - This method does the work. Always successful.
|
// runOnMethod - This method does the work. Always successful.
|
||||||
//
|
//
|
||||||
bool runOnMethod(Method *M) {
|
bool runOnMethod(Function *F) {
|
||||||
return doit(M, TraceBasicBlockExits, TraceMethodExits, PrintfMeth);
|
return doit(F, TraceBasicBlockExits, TraceFunctionExits, PrintfFunc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
@ -72,14 +72,14 @@ bool InsertTraceCode::doInitialization(Module *M) {
|
|||||||
const MethodType *MTy =
|
const MethodType *MTy =
|
||||||
MethodType::get(Type::IntTy, vector<const Type*>(1, SBP), true);
|
MethodType::get(Type::IntTy, vector<const Type*>(1, SBP), true);
|
||||||
|
|
||||||
if (Value *Meth = ST->lookup(PointerType::get(MTy), "printf")) {
|
if (Value *Func = ST->lookup(PointerType::get(MTy), "printf")) {
|
||||||
PrintfMeth = cast<Method>(Meth);
|
PrintfFunc = cast<Function>(Func);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new method and add it to the module
|
// Create a new method and add it to the module
|
||||||
PrintfMeth = new Method(MTy, false, "printf");
|
PrintfFunc = new Function(MTy, false, "printf");
|
||||||
M->getMethodList().push_back(PrintfMeth);
|
M->getFunctionList().push_back(PrintfFunc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ static string getPrintfCodeFor(const Value *V) {
|
|||||||
|
|
||||||
|
|
||||||
static void InsertPrintInst(Value *V, BasicBlock *BB, BasicBlock::iterator &BBI,
|
static void InsertPrintInst(Value *V, BasicBlock *BB, BasicBlock::iterator &BBI,
|
||||||
string Message, Method *Printf) {
|
string Message, Function *Printf) {
|
||||||
// Escape Message by replacing all % characters with %% chars.
|
// Escape Message by replacing all % characters with %% chars.
|
||||||
unsigned Offset = 0;
|
unsigned Offset = 0;
|
||||||
while ((Offset = Message.find('%', Offset)) != string::npos) {
|
while ((Offset = Message.find('%', Offset)) != string::npos) {
|
||||||
@ -184,7 +184,7 @@ static void InsertPrintInst(Value *V, BasicBlock *BB, BasicBlock::iterator &BBI,
|
|||||||
|
|
||||||
static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
|
static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
|
||||||
BasicBlock::iterator &BBI,
|
BasicBlock::iterator &BBI,
|
||||||
const string &Message, Method *Printf) {
|
const string &Message, Function *Printf) {
|
||||||
std::ostringstream OutStr;
|
std::ostringstream OutStr;
|
||||||
if (V) WriteAsOperand(OutStr, V);
|
if (V) WriteAsOperand(OutStr, V);
|
||||||
InsertPrintInst(V, BB, BBI, Message+OutStr.str()+" = ", Printf);
|
InsertPrintInst(V, BB, BBI, Message+OutStr.str()+" = ", Printf);
|
||||||
@ -195,15 +195,15 @@ static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
|
|||||||
// for each value in valueVec[] that is live at the end of that basic block,
|
// for each value in valueVec[] that is live at the end of that basic block,
|
||||||
// or that is stored to memory in this basic block.
|
// or that is stored to memory in this basic block.
|
||||||
// If the value is stored to memory, we load it back before printing
|
// If the value is stored to memory, we load it back before printing
|
||||||
// We also return all such loaded values in the vector valuesStoredInMethod
|
// We also return all such loaded values in the vector valuesStoredInFunction
|
||||||
// for printing at the exit from the method. (Note that in each invocation
|
// for printing at the exit from the method. (Note that in each invocation
|
||||||
// of the method, this will only get the last value stored for each static
|
// of the method, this will only get the last value stored for each static
|
||||||
// store instruction).
|
// store instruction).
|
||||||
// *bb must be the block in which the value is computed;
|
// *bb must be the block in which the value is computed;
|
||||||
// this is not checked here.
|
// this is not checked here.
|
||||||
//
|
//
|
||||||
static void TraceValuesAtBBExit(BasicBlock *BB, Method *Printf,
|
static void TraceValuesAtBBExit(BasicBlock *BB, Function *Printf,
|
||||||
vector<Instruction*> *valuesStoredInMethod) {
|
vector<Instruction*> *valuesStoredInFunction) {
|
||||||
// Get an iterator to point to the insertion location, which is
|
// Get an iterator to point to the insertion location, which is
|
||||||
// just before the terminator instruction.
|
// just before the terminator instruction.
|
||||||
//
|
//
|
||||||
@ -239,19 +239,19 @@ static void TraceValuesAtBBExit(BasicBlock *BB, Method *Printf,
|
|||||||
IE = Insts.end(); II != IE; ++II) {
|
IE = Insts.end(); II != IE; ++II) {
|
||||||
Instruction *I = *II;
|
Instruction *I = *II;
|
||||||
if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
||||||
assert(valuesStoredInMethod &&
|
assert(valuesStoredInFunction &&
|
||||||
"Should not be printing a store instruction at method exit");
|
"Should not be printing a store instruction at method exit");
|
||||||
LoadInst *LI = new LoadInst(SI->getPointerOperand(), SI->copyIndices(),
|
LoadInst *LI = new LoadInst(SI->getPointerOperand(), SI->copyIndices(),
|
||||||
"reload");
|
"reload");
|
||||||
InsertPos = BB->getInstList().insert(InsertPos, LI) + 1;
|
InsertPos = BB->getInstList().insert(InsertPos, LI) + 1;
|
||||||
valuesStoredInMethod->push_back(LI);
|
valuesStoredInFunction->push_back(LI);
|
||||||
}
|
}
|
||||||
if (ShouldTraceValue(I))
|
if (ShouldTraceValue(I))
|
||||||
InsertVerbosePrintInst(I, BB, InsertPos, " ", Printf);
|
InsertVerbosePrintInst(I, BB, InsertPos, " ", Printf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void InsertCodeToShowMethodEntry(Method *M, Method *Printf) {
|
static inline void InsertCodeToShowFunctionEntry(Function *M, Function *Printf){
|
||||||
// Get an iterator to point to the insertion location
|
// Get an iterator to point to the insertion location
|
||||||
BasicBlock *BB = M->getEntryNode();
|
BasicBlock *BB = M->getEntryNode();
|
||||||
BasicBlock::iterator BBI = BB->begin();
|
BasicBlock::iterator BBI = BB->begin();
|
||||||
@ -261,9 +261,9 @@ static inline void InsertCodeToShowMethodEntry(Method *M, Method *Printf) {
|
|||||||
InsertPrintInst(0, BB, BBI, "ENTERING METHOD: " + OutStr.str(), Printf);
|
InsertPrintInst(0, BB, BBI, "ENTERING METHOD: " + OutStr.str(), Printf);
|
||||||
|
|
||||||
// Now print all the incoming arguments
|
// Now print all the incoming arguments
|
||||||
const Method::ArgumentListType &argList = M->getArgumentList();
|
const Function::ArgumentListType &argList = M->getArgumentList();
|
||||||
unsigned ArgNo = 0;
|
unsigned ArgNo = 0;
|
||||||
for (Method::ArgumentListType::const_iterator
|
for (Function::ArgumentListType::const_iterator
|
||||||
I = argList.begin(), E = argList.end(); I != E; ++I, ++ArgNo) {
|
I = argList.begin(), E = argList.end(); I != E; ++I, ++ArgNo) {
|
||||||
InsertVerbosePrintInst(*I, BB, BBI,
|
InsertVerbosePrintInst(*I, BB, BBI,
|
||||||
" Arg #" + utostr(ArgNo), Printf);
|
" Arg #" + utostr(ArgNo), Printf);
|
||||||
@ -271,7 +271,8 @@ static inline void InsertCodeToShowMethodEntry(Method *M, Method *Printf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void InsertCodeToShowMethodExit(BasicBlock *BB, Method *Printf) {
|
static inline void InsertCodeToShowFunctionExit(BasicBlock *BB,
|
||||||
|
Function *Printf) {
|
||||||
// Get an iterator to point to the insertion location
|
// Get an iterator to point to the insertion location
|
||||||
BasicBlock::iterator BBI = BB->end()-1;
|
BasicBlock::iterator BBI = BB->end()-1;
|
||||||
ReturnInst *Ret = cast<ReturnInst>(*BBI);
|
ReturnInst *Ret = cast<ReturnInst>(*BBI);
|
||||||
@ -286,34 +287,34 @@ static inline void InsertCodeToShowMethodExit(BasicBlock *BB, Method *Printf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool InsertTraceCode::doit(Method *M, bool traceBasicBlockExits,
|
bool InsertTraceCode::doit(Function *M, bool traceBasicBlockExits,
|
||||||
bool traceMethodEvents, Method *Printf) {
|
bool traceFunctionEvents, Function *Printf) {
|
||||||
if (!traceBasicBlockExits && !traceMethodEvents)
|
if (!traceBasicBlockExits && !traceFunctionEvents)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
vector<Instruction*> valuesStoredInMethod;
|
vector<Instruction*> valuesStoredInFunction;
|
||||||
vector<BasicBlock*> exitBlocks;
|
vector<BasicBlock*> exitBlocks;
|
||||||
|
|
||||||
if (traceMethodEvents)
|
if (traceFunctionEvents)
|
||||||
InsertCodeToShowMethodEntry(M, Printf);
|
InsertCodeToShowFunctionEntry(M, Printf);
|
||||||
|
|
||||||
for (Method::iterator BI = M->begin(); BI != M->end(); ++BI) {
|
for (Function::iterator BI = M->begin(); BI != M->end(); ++BI) {
|
||||||
BasicBlock *BB = *BI;
|
BasicBlock *BB = *BI;
|
||||||
if (isa<ReturnInst>(BB->getTerminator()))
|
if (isa<ReturnInst>(BB->getTerminator()))
|
||||||
exitBlocks.push_back(BB); // record this as an exit block
|
exitBlocks.push_back(BB); // record this as an exit block
|
||||||
|
|
||||||
if (traceBasicBlockExits)
|
if (traceBasicBlockExits)
|
||||||
TraceValuesAtBBExit(BB, Printf, &valuesStoredInMethod);
|
TraceValuesAtBBExit(BB, Printf, &valuesStoredInFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traceMethodEvents)
|
if (traceFunctionEvents)
|
||||||
for (unsigned i=0; i < exitBlocks.size(); ++i) {
|
for (unsigned i=0; i < exitBlocks.size(); ++i) {
|
||||||
#if 0
|
#if 0
|
||||||
TraceValuesAtBBExit(valuesStoredInMethod, exitBlocks[i], module,
|
TraceValuesAtBBExit(valuesStoredInFunction, exitBlocks[i], module,
|
||||||
/*indent*/ 0, /*isMethodExit*/ true,
|
/*indent*/ 0, /*isFunctionExit*/ true,
|
||||||
/*valuesStoredInMethod*/ NULL);
|
/*valuesStoredInFunction*/ NULL);
|
||||||
#endif
|
#endif
|
||||||
InsertCodeToShowMethodExit(exitBlocks[i], Printf);
|
InsertCodeToShowFunctionExit(exitBlocks[i], Printf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "llvm/Transforms/Scalar/DCE.h"
|
#include "llvm/Transforms/Scalar/DCE.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/iTerminators.h"
|
#include "llvm/iTerminators.h"
|
||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
@ -91,7 +91,7 @@ static bool RemoveSingularPHIs(BasicBlock *BB) {
|
|||||||
//cerr << "Killing PHIs from " << BB;
|
//cerr << "Killing PHIs from " << BB;
|
||||||
//cerr << "Pred #0 = " << *pred_begin(BB);
|
//cerr << "Pred #0 = " << *pred_begin(BB);
|
||||||
|
|
||||||
//cerr << "Method == " << BB->getParent();
|
//cerr << "Function == " << BB->getParent();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
PHINode *PN = cast<PHINode>(I);
|
PHINode *PN = cast<PHINode>(I);
|
||||||
@ -167,9 +167,9 @@ static bool PropogatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
|
|||||||
//
|
//
|
||||||
// WARNING: The entry node of a method may not be simplified.
|
// WARNING: The entry node of a method may not be simplified.
|
||||||
//
|
//
|
||||||
bool SimplifyCFG(Method::iterator &BBIt) {
|
bool SimplifyCFG(Function::iterator &BBIt) {
|
||||||
BasicBlock *BB = *BBIt;
|
BasicBlock *BB = *BBIt;
|
||||||
Method *M = BB->getParent();
|
Function *M = BB->getParent();
|
||||||
|
|
||||||
assert(BB && BB->getParent() && "Block not embedded in method!");
|
assert(BB && BB->getParent() && "Block not embedded in method!");
|
||||||
assert(BB->getTerminator() && "Degenerate basic block encountered!");
|
assert(BB->getTerminator() && "Degenerate basic block encountered!");
|
||||||
@ -226,7 +226,7 @@ bool SimplifyCFG(Method::iterator &BBIt) {
|
|||||||
Succ->setName(BB->getName());
|
Succ->setName(BB->getName());
|
||||||
delete BB; // Delete basic block
|
delete BB; // Delete basic block
|
||||||
|
|
||||||
//cerr << "Method after removal: \n" << M;
|
//cerr << "Function after removal: \n" << M;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,13 +279,13 @@ bool SimplifyCFG(Method::iterator &BBIt) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DoDCEPass(Method *M) {
|
static bool DoDCEPass(Function *F) {
|
||||||
Method::iterator BBIt, BBEnd = M->end();
|
Function::iterator BBIt, BBEnd = F->end();
|
||||||
if (M->begin() == BBEnd) return false; // Nothing to do
|
if (F->begin() == BBEnd) return false; // Nothing to do
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
// Loop through now and remove instructions that have no uses...
|
// Loop through now and remove instructions that have no uses...
|
||||||
for (BBIt = M->begin(); BBIt != BBEnd; ++BBIt) {
|
for (BBIt = F->begin(); BBIt != BBEnd; ++BBIt) {
|
||||||
Changed |= RemoveUnusedDefs((*BBIt)->getInstList());
|
Changed |= RemoveUnusedDefs((*BBIt)->getInstList());
|
||||||
Changed |= RemoveSingularPHIs(*BBIt);
|
Changed |= RemoveSingularPHIs(*BBIt);
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ static bool DoDCEPass(Method *M) {
|
|||||||
// Loop over all of the basic blocks (except the first one) and remove them
|
// Loop over all of the basic blocks (except the first one) and remove them
|
||||||
// if they are unneeded...
|
// if they are unneeded...
|
||||||
//
|
//
|
||||||
for (BBIt = M->begin(), ++BBIt; BBIt != M->end(); ) {
|
for (BBIt = F->begin(), ++BBIt; BBIt != F->end(); ) {
|
||||||
if (SimplifyCFG(BBIt)) {
|
if (SimplifyCFG(BBIt)) {
|
||||||
Changed = true;
|
Changed = true;
|
||||||
} else {
|
} else {
|
||||||
@ -312,11 +312,11 @@ static bool RemoveUnusedGlobalValues(Module *Mod) {
|
|||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
for (Module::iterator MI = Mod->begin(); MI != Mod->end(); ) {
|
for (Module::iterator MI = Mod->begin(); MI != Mod->end(); ) {
|
||||||
Method *Meth = *MI;
|
Function *Meth = *MI;
|
||||||
if (Meth->isExternal() && Meth->use_size() == 0) {
|
if (Meth->isExternal() && Meth->use_size() == 0) {
|
||||||
// No references to prototype?
|
// No references to prototype?
|
||||||
//cerr << "Removing method proto: " << Meth->getName() << endl;
|
//cerr << "Removing method proto: " << Meth->getName() << endl;
|
||||||
delete Mod->getMethodList().remove(MI); // Remove prototype
|
delete Mod->getFunctionList().remove(MI); // Remove prototype
|
||||||
// Remove moves iterator to point to the next one automatically
|
// Remove moves iterator to point to the next one automatically
|
||||||
Changed = true;
|
Changed = true;
|
||||||
} else {
|
} else {
|
||||||
@ -351,9 +351,9 @@ namespace {
|
|||||||
// It is possible that we may require multiple passes over the code to fully
|
// It is possible that we may require multiple passes over the code to fully
|
||||||
// eliminate dead code. Iterate until we are done.
|
// eliminate dead code. Iterate until we are done.
|
||||||
//
|
//
|
||||||
virtual bool runOnMethod(Method *M) {
|
virtual bool runOnMethod(Function *F) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
while (DoDCEPass(M)) Changed = true;
|
while (DoDCEPass(F)) Changed = true;
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/InstrTypes.h"
|
#include "llvm/InstrTypes.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
@ -38,7 +38,7 @@ using std::cerr;
|
|||||||
// an interval invariant computation.
|
// an interval invariant computation.
|
||||||
//
|
//
|
||||||
static bool isLoopInvariant(cfg::Interval *Int, Value *V) {
|
static bool isLoopInvariant(cfg::Interval *Int, Value *V) {
|
||||||
assert(isa<Constant>(V) || isa<Instruction>(V) || isa<MethodArgument>(V));
|
assert(isa<Constant>(V) || isa<Instruction>(V) || isa<FunctionArgument>(V));
|
||||||
|
|
||||||
if (!isa<Instruction>(V))
|
if (!isa<Instruction>(V))
|
||||||
return true; // Constants and arguments are always loop invariant
|
return true; // Constants and arguments are always loop invariant
|
||||||
@ -181,7 +181,7 @@ static PHINode *InjectSimpleInductionVariable(cfg::Interval *Int) {
|
|||||||
std::string PHIName, AddName;
|
std::string PHIName, AddName;
|
||||||
|
|
||||||
BasicBlock *Header = Int->getHeaderNode();
|
BasicBlock *Header = Int->getHeaderNode();
|
||||||
Method *M = Header->getParent();
|
Function *M = Header->getParent();
|
||||||
|
|
||||||
if (M->hasSymbolTable()) {
|
if (M->hasSymbolTable()) {
|
||||||
// Only name the induction variable if the method isn't stripped.
|
// Only name the induction variable if the method isn't stripped.
|
||||||
@ -373,7 +373,7 @@ static bool ProcessIntervalPartition(cfg::IntervalPartition &IP) {
|
|||||||
// This function loops over an interval partition of a program, reducing it
|
// This function loops over an interval partition of a program, reducing it
|
||||||
// until the graph is gone.
|
// until the graph is gone.
|
||||||
//
|
//
|
||||||
bool InductionVariableCannonicalize::doIt(Method *M,
|
bool InductionVariableCannonicalize::doIt(Function *M,
|
||||||
cfg::IntervalPartition &IP) {
|
cfg::IntervalPartition &IP) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
@ -399,8 +399,8 @@ bool InductionVariableCannonicalize::doIt(Method *M,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool InductionVariableCannonicalize::runOnMethod(Method *M) {
|
bool InductionVariableCannonicalize::runOnMethod(Function *F) {
|
||||||
return doIt(M, getAnalysis<cfg::IntervalPartition>());
|
return doIt(F, getAnalysis<cfg::IntervalPartition>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// getAnalysisUsageInfo - This function works on the call graph of a module.
|
// getAnalysisUsageInfo - This function works on the call graph of a module.
|
||||||
|
@ -17,10 +17,9 @@
|
|||||||
|
|
||||||
#include "llvm/Transforms/Scalar/ConstantProp.h"
|
#include "llvm/Transforms/Scalar/ConstantProp.h"
|
||||||
#include "llvm/Transforms/Scalar/ConstantHandling.h"
|
#include "llvm/Transforms/Scalar/ConstantHandling.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/ConstantVals.h"
|
#include "llvm/ConstantVals.h"
|
||||||
#include "llvm/InstrTypes.h"
|
|
||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
#include "llvm/iMemory.h"
|
#include "llvm/iMemory.h"
|
||||||
#include "llvm/iTerminators.h"
|
#include "llvm/iTerminators.h"
|
||||||
@ -87,7 +86,7 @@ public:
|
|||||||
// It's public interface consists of a constructor and a doSCCP() method.
|
// It's public interface consists of a constructor and a doSCCP() method.
|
||||||
//
|
//
|
||||||
class SCCP {
|
class SCCP {
|
||||||
Method *M; // The method that we are working on...
|
Function *M; // The function that we are working on
|
||||||
|
|
||||||
std::set<BasicBlock*> BBExecutable;// The basic blocks that are executable
|
std::set<BasicBlock*> BBExecutable;// The basic blocks that are executable
|
||||||
std::map<Value*, InstVal> ValueState; // The state each value is in...
|
std::map<Value*, InstVal> ValueState; // The state each value is in...
|
||||||
@ -101,7 +100,7 @@ class SCCP {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
// SCCP Ctor - Save the method to operate on...
|
// SCCP Ctor - Save the method to operate on...
|
||||||
inline SCCP(Method *m) : M(m) {}
|
inline SCCP(Function *f) : M(f) {}
|
||||||
|
|
||||||
// doSCCP() - Run the Sparse Conditional Constant Propogation algorithm, and
|
// doSCCP() - Run the Sparse Conditional Constant Propogation algorithm, and
|
||||||
// return true if the method was modified.
|
// return true if the method was modified.
|
||||||
@ -142,8 +141,8 @@ private:
|
|||||||
|
|
||||||
// getValueState - Return the InstVal object that corresponds to the value.
|
// getValueState - Return the InstVal object that corresponds to the value.
|
||||||
// This function is neccesary because not all values should start out in the
|
// This function is neccesary because not all values should start out in the
|
||||||
// underdefined state... MethodArgument's should be overdefined, and constants
|
// underdefined state... FunctionArgument's should be overdefined, and
|
||||||
// should be marked as constants. If a value is not known to be an
|
// constants should be marked as constants. If a value is not known to be an
|
||||||
// Instruction object, then use this accessor to get its value from the map.
|
// Instruction object, then use this accessor to get its value from the map.
|
||||||
//
|
//
|
||||||
inline InstVal &getValueState(Value *V) {
|
inline InstVal &getValueState(Value *V) {
|
||||||
@ -152,7 +151,7 @@ private:
|
|||||||
|
|
||||||
if (Constant *CPV = dyn_cast<Constant>(V)) { // Constants are constant
|
if (Constant *CPV = dyn_cast<Constant>(V)) { // Constants are constant
|
||||||
ValueState[CPV].markConstant(CPV);
|
ValueState[CPV].markConstant(CPV);
|
||||||
} else if (isa<MethodArgument>(V)) { // MethodArgs are overdefined
|
} else if (isa<FunctionArgument>(V)) { // FuncArgs are overdefined
|
||||||
ValueState[V].markOverdefined();
|
ValueState[V].markOverdefined();
|
||||||
}
|
}
|
||||||
// All others are underdefined by default...
|
// All others are underdefined by default...
|
||||||
@ -235,7 +234,8 @@ bool SCCP::doSCCP() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
for (Method::iterator BBI = M->begin(), BBEnd = M->end(); BBI != BBEnd; ++BBI)
|
for (Function::iterator BBI = M->begin(), BBEnd = M->end();
|
||||||
|
BBI != BBEnd; ++BBI)
|
||||||
if (!BBExecutable.count(*BBI))
|
if (!BBExecutable.count(*BBI))
|
||||||
cerr << "BasicBlock Dead:" << *BBI;
|
cerr << "BasicBlock Dead:" << *BBI;
|
||||||
#endif
|
#endif
|
||||||
@ -245,7 +245,7 @@ bool SCCP::doSCCP() {
|
|||||||
// constants if we have found them to be of constant values.
|
// constants if we have found them to be of constant values.
|
||||||
//
|
//
|
||||||
bool MadeChanges = false;
|
bool MadeChanges = false;
|
||||||
for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) {
|
for (Function::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) {
|
||||||
BasicBlock *BB = *MI;
|
BasicBlock *BB = *MI;
|
||||||
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
|
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
|
||||||
Instruction *Inst = *BI;
|
Instruction *Inst = *BI;
|
||||||
@ -380,8 +380,8 @@ void SCCP::UpdateInstruction(Instruction *I) {
|
|||||||
//===-----------------------------------------------------------------===//
|
//===-----------------------------------------------------------------===//
|
||||||
// Handle Terminator instructions...
|
// Handle Terminator instructions...
|
||||||
//
|
//
|
||||||
case Instruction::Ret: return; // Method return doesn't affect anything
|
case Instruction::Ret: return; // Function return doesn't affect anything
|
||||||
case Instruction::Br: { // Handle conditional branches...
|
case Instruction::Br: { // Handle conditional branches...
|
||||||
BranchInst *BI = cast<BranchInst>(I);
|
BranchInst *BI = cast<BranchInst>(I);
|
||||||
if (BI->isUnconditional())
|
if (BI->isUnconditional())
|
||||||
return; // Unconditional branches are already handled!
|
return; // Unconditional branches are already handled!
|
||||||
@ -509,8 +509,8 @@ namespace {
|
|||||||
// to prove whether a value is constant and whether blocks are used.
|
// to prove whether a value is constant and whether blocks are used.
|
||||||
//
|
//
|
||||||
struct SCCPPass : public MethodPass {
|
struct SCCPPass : public MethodPass {
|
||||||
inline bool runOnMethod(Method *M) {
|
inline bool runOnMethod(Function *F) {
|
||||||
SCCP S(M);
|
SCCP S(F);
|
||||||
return S.doSCCP();
|
return S.doSCCP();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "llvm/Transforms/Linker.h"
|
#include "llvm/Transforms/Linker.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
@ -165,8 +165,8 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
|
|||||||
(V = ST->lookup(SGV->getType(), SGV->getName())) &&
|
(V = ST->lookup(SGV->getType(), SGV->getName())) &&
|
||||||
cast<GlobalVariable>(V)->hasExternalLinkage()) {
|
cast<GlobalVariable>(V)->hasExternalLinkage()) {
|
||||||
// The same named thing is a global variable, because the only two things
|
// The same named thing is a global variable, because the only two things
|
||||||
// that may be in a module level symbol table are Global Vars and Methods,
|
// that may be in a module level symbol table are Global Vars and
|
||||||
// and they both have distinct, nonoverlapping, possible types.
|
// Functions, and they both have distinct, nonoverlapping, possible types.
|
||||||
//
|
//
|
||||||
GlobalVariable *DGV = cast<GlobalVariable>(V);
|
GlobalVariable *DGV = cast<GlobalVariable>(V);
|
||||||
|
|
||||||
@ -231,13 +231,13 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkMethodProtos - Link the methods together between the two modules, without
|
// LinkFunctionProtos - Link the functions together between the two modules,
|
||||||
// doing method bodies... this just adds external method prototypes to the Dest
|
// without doing method bodies... this just adds external method prototypes to
|
||||||
// method...
|
// the Dest function...
|
||||||
//
|
//
|
||||||
static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
static bool LinkFunctionProtos(Module *Dest, const Module *Src,
|
||||||
map<const Value*, Value*> &ValueMap,
|
map<const Value*, Value*> &ValueMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
// We will need a module level symbol table if the src module has a module
|
// We will need a module level symbol table if the src module has a module
|
||||||
// level symbol table...
|
// level symbol table...
|
||||||
SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0;
|
SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0;
|
||||||
@ -245,7 +245,7 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
// Loop over all of the methods in the src module, mapping them over as we go
|
// Loop over all of the methods in the src module, mapping them over as we go
|
||||||
//
|
//
|
||||||
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const Method *SM = *I; // SrcMethod
|
const Function *SM = *I; // SrcFunction
|
||||||
Value *V;
|
Value *V;
|
||||||
|
|
||||||
// If the method has a name, and that name is already in use in the
|
// If the method has a name, and that name is already in use in the
|
||||||
@ -253,29 +253,29 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
//
|
//
|
||||||
if (SM->hasExternalLinkage() && SM->hasName() &&
|
if (SM->hasExternalLinkage() && SM->hasName() &&
|
||||||
(V = ST->lookup(SM->getType(), SM->getName())) &&
|
(V = ST->lookup(SM->getType(), SM->getName())) &&
|
||||||
cast<Method>(V)->hasExternalLinkage()) {
|
cast<Function>(V)->hasExternalLinkage()) {
|
||||||
// The same named thing is a Method, because the only two things
|
// The same named thing is a Function, because the only two things
|
||||||
// that may be in a module level symbol table are Global Vars and Methods,
|
// that may be in a module level symbol table are Global Vars and
|
||||||
// and they both have distinct, nonoverlapping, possible types.
|
// Functions, and they both have distinct, nonoverlapping, possible types.
|
||||||
//
|
//
|
||||||
Method *DM = cast<Method>(V); // DestMethod
|
Function *DM = cast<Function>(V); // DestFunction
|
||||||
|
|
||||||
// Check to make sure the method is not defined in both modules...
|
// Check to make sure the method is not defined in both modules...
|
||||||
if (!SM->isExternal() && !DM->isExternal())
|
if (!SM->isExternal() && !DM->isExternal())
|
||||||
return Error(Err, "Method '" +
|
return Error(Err, "Function '" +
|
||||||
SM->getMethodType()->getDescription() + "':\"" +
|
SM->getMethodType()->getDescription() + "':\"" +
|
||||||
SM->getName() + "\" - Method is already defined!");
|
SM->getName() + "\" - Function is already defined!");
|
||||||
|
|
||||||
// Otherwise, just remember this mapping...
|
// Otherwise, just remember this mapping...
|
||||||
ValueMap.insert(std::make_pair(SM, DM));
|
ValueMap.insert(std::make_pair(SM, DM));
|
||||||
} else {
|
} else {
|
||||||
// Method does not already exist, simply insert an external method
|
// Function does not already exist, simply insert an external method
|
||||||
// signature identical to SM into the dest module...
|
// signature identical to SM into the dest module...
|
||||||
Method *DM = new Method(SM->getMethodType(), SM->hasInternalLinkage(),
|
Function *DM = new Function(SM->getMethodType(), SM->hasInternalLinkage(),
|
||||||
SM->getName());
|
SM->getName());
|
||||||
|
|
||||||
// Add the method signature to the dest module...
|
// Add the method signature to the dest module...
|
||||||
Dest->getMethodList().push_back(DM);
|
Dest->getFunctionList().push_back(DM);
|
||||||
|
|
||||||
// ... and remember this mapping...
|
// ... and remember this mapping...
|
||||||
ValueMap.insert(std::make_pair(SM, DM));
|
ValueMap.insert(std::make_pair(SM, DM));
|
||||||
@ -284,24 +284,24 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkMethodBody - Copy the source method over into the dest method and fix up
|
// LinkFunctionBody - Copy the source method over into the dest method
|
||||||
// references to values. At this point we know that Dest is an external method,
|
// and fix up references to values. At this point we know that Dest
|
||||||
// and that Src is not.
|
// is an external method, and that Src is not.
|
||||||
//
|
//
|
||||||
static bool LinkMethodBody(Method *Dest, const Method *Src,
|
static bool LinkFunctionBody(Function *Dest, const Function *Src,
|
||||||
const map<const Value*, Value*> &GlobalMap,
|
const map<const Value*, Value*> &GlobalMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
assert(Src && Dest && Dest->isExternal() && !Src->isExternal());
|
assert(Src && Dest && Dest->isExternal() && !Src->isExternal());
|
||||||
map<const Value*, Value*> LocalMap; // Map for method local values
|
map<const Value*, Value*> LocalMap; // Map for method local values
|
||||||
|
|
||||||
// Go through and convert method arguments over...
|
// Go through and convert method arguments over...
|
||||||
for (Method::ArgumentListType::const_iterator
|
for (Function::ArgumentListType::const_iterator
|
||||||
I = Src->getArgumentList().begin(),
|
I = Src->getArgumentList().begin(),
|
||||||
E = Src->getArgumentList().end(); I != E; ++I) {
|
E = Src->getArgumentList().end(); I != E; ++I) {
|
||||||
const MethodArgument *SMA = *I;
|
const FunctionArgument *SMA = *I;
|
||||||
|
|
||||||
// Create the new method argument and add to the dest method...
|
// Create the new method argument and add to the dest method...
|
||||||
MethodArgument *DMA = new MethodArgument(SMA->getType(), SMA->getName());
|
FunctionArgument *DMA = new FunctionArgument(SMA->getType(),SMA->getName());
|
||||||
Dest->getArgumentList().push_back(DMA);
|
Dest->getArgumentList().push_back(DMA);
|
||||||
|
|
||||||
// Add a mapping to our local map
|
// Add a mapping to our local map
|
||||||
@ -310,7 +310,7 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
|
|
||||||
// Loop over all of the basic blocks, copying the instructions over...
|
// Loop over all of the basic blocks, copying the instructions over...
|
||||||
//
|
//
|
||||||
for (Method::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Function::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const BasicBlock *SBB = *I;
|
const BasicBlock *SBB = *I;
|
||||||
|
|
||||||
// Create new basic block and add to mapping and the Dest method...
|
// Create new basic block and add to mapping and the Dest method...
|
||||||
@ -338,7 +338,7 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
// in the Source method as operands. Loop through all of the operands of the
|
// in the Source method as operands. Loop through all of the operands of the
|
||||||
// methods and patch them up to point to the local versions...
|
// methods and patch them up to point to the local versions...
|
||||||
//
|
//
|
||||||
for (Method::iterator BI = Dest->begin(), BE = Dest->end();
|
for (Function::iterator BI = Dest->begin(), BE = Dest->end();
|
||||||
BI != BE; ++BI) {
|
BI != BE; ++BI) {
|
||||||
BasicBlock *BB = *BI;
|
BasicBlock *BB = *BI;
|
||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||||
@ -354,30 +354,30 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// LinkMethodBodies - Link in the method bodies that are defined in the source
|
// LinkFunctionBodies - Link in the method bodies that are defined in the source
|
||||||
// module into the DestModule. This consists basically of copying the method
|
// module into the DestModule. This consists basically of copying the method
|
||||||
// over and fixing up references to values.
|
// over and fixing up references to values.
|
||||||
//
|
//
|
||||||
static bool LinkMethodBodies(Module *Dest, const Module *Src,
|
static bool LinkFunctionBodies(Module *Dest, const Module *Src,
|
||||||
map<const Value*, Value*> &ValueMap,
|
map<const Value*, Value*> &ValueMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
|
|
||||||
// Loop over all of the methods in the src module, mapping them over as we go
|
// Loop over all of the methods in the src module, mapping them over as we go
|
||||||
//
|
//
|
||||||
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const Method *SM = *I; // Source Method
|
const Function *SM = *I; // Source Function
|
||||||
if (!SM->isExternal()) { // No body if method is external
|
if (!SM->isExternal()) { // No body if method is external
|
||||||
Method *DM = cast<Method>(ValueMap[SM]); // Destination method
|
Function *DM = cast<Function>(ValueMap[SM]); // Destination method
|
||||||
|
|
||||||
// DM not external SM external?
|
// DM not external SM external?
|
||||||
if (!DM->isExternal()) {
|
if (!DM->isExternal()) {
|
||||||
if (Err)
|
if (Err)
|
||||||
*Err = "Method '" + (SM->hasName() ? SM->getName() : string("")) +
|
*Err = "Function '" + (SM->hasName() ? SM->getName() : string("")) +
|
||||||
"' body multiply defined!";
|
"' body multiply defined!";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LinkMethodBody(DM, SM, ValueMap, Err)) return true;
|
if (LinkFunctionBody(DM, SM, ValueMap, Err)) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -418,13 +418,13 @@ bool LinkModules(Module *Dest, const Module *Src, string *ErrorMsg = 0) {
|
|||||||
// We do this so that when we begin processing method bodies, all of the
|
// We do this so that when we begin processing method bodies, all of the
|
||||||
// global values that may be referenced are available in our ValueMap.
|
// global values that may be referenced are available in our ValueMap.
|
||||||
//
|
//
|
||||||
if (LinkMethodProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
|
if (LinkFunctionProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
|
||||||
|
|
||||||
// Link in the method bodies that are defined in the source module into the
|
// Link in the method bodies that are defined in the source module into the
|
||||||
// DestModule. This consists basically of copying the method over and fixing
|
// DestModule. This consists basically of copying the method over and fixing
|
||||||
// up references to values.
|
// up references to values.
|
||||||
//
|
//
|
||||||
if (LinkMethodBodies(Dest, Src, ValueMap, ErrorMsg)) return true;
|
if (LinkFunctionBodies(Dest, Src, ValueMap, ErrorMsg)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -25,13 +25,13 @@ namespace {
|
|||||||
// calls.
|
// calls.
|
||||||
//
|
//
|
||||||
class LowerAllocations : public BasicBlockPass {
|
class LowerAllocations : public BasicBlockPass {
|
||||||
Method *MallocMeth; // Methods in the module we are processing
|
Function *MallocFunc; // Functions in the module we are processing
|
||||||
Method *FreeMeth; // Initialized by doInitialization
|
Function *FreeFunc; // Initialized by doInitialization
|
||||||
|
|
||||||
const TargetData &DataLayout;
|
const TargetData &DataLayout;
|
||||||
public:
|
public:
|
||||||
inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
|
inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
|
||||||
MallocMeth = FreeMeth = 0;
|
MallocFunc = FreeFunc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// doPassInitialization - For the lower allocations pass, this ensures that a
|
// doPassInitialization - For the lower allocations pass, this ensures that a
|
||||||
@ -49,10 +49,10 @@ public:
|
|||||||
// instruction.
|
// instruction.
|
||||||
//
|
//
|
||||||
class RaiseAllocations : public BasicBlockPass {
|
class RaiseAllocations : public BasicBlockPass {
|
||||||
Method *MallocMeth; // Methods in the module we are processing
|
Function *MallocFunc; // Functions in the module we are processing
|
||||||
Method *FreeMeth; // Initialized by doPassInitializationVirt
|
Function *FreeFunc; // Initialized by doPassInitializationVirt
|
||||||
public:
|
public:
|
||||||
inline RaiseAllocations() : MallocMeth(0), FreeMeth(0) {}
|
inline RaiseAllocations() : MallocFunc(0), FreeFunc(0) {}
|
||||||
|
|
||||||
// doPassInitialization - For the raise allocations pass, this finds a
|
// doPassInitialization - For the raise allocations pass, this finds a
|
||||||
// declaration for malloc and free if they exist.
|
// declaration for malloc and free if they exist.
|
||||||
@ -82,10 +82,10 @@ bool LowerAllocations::doInitialization(Module *M) {
|
|||||||
|
|
||||||
// Check for a definition of malloc
|
// Check for a definition of malloc
|
||||||
if (Value *V = SymTab->lookup(PointerType::get(MallocType), "malloc")) {
|
if (Value *V = SymTab->lookup(PointerType::get(MallocType), "malloc")) {
|
||||||
MallocMeth = cast<Method>(V); // Yup, got it
|
MallocFunc = cast<Function>(V); // Yup, got it
|
||||||
} else { // Nope, add one
|
} else { // Nope, add one
|
||||||
M->getMethodList().push_back(MallocMeth = new Method(MallocType, false,
|
M->getFunctionList().push_back(MallocFunc = new Function(MallocType, false,
|
||||||
"malloc"));
|
"malloc"));
|
||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,9 +96,10 @@ bool LowerAllocations::doInitialization(Module *M) {
|
|||||||
|
|
||||||
// Check for a definition of free
|
// Check for a definition of free
|
||||||
if (Value *V = SymTab->lookup(PointerType::get(FreeType), "free")) {
|
if (Value *V = SymTab->lookup(PointerType::get(FreeType), "free")) {
|
||||||
FreeMeth = cast<Method>(V); // Yup, got it
|
FreeFunc = cast<Function>(V); // Yup, got it
|
||||||
} else { // Nope, add one
|
} else { // Nope, add one
|
||||||
M->getMethodList().push_back(FreeMeth = new Method(FreeType, false,"free"));
|
FreeFunc = new Function(FreeType, false,"free");
|
||||||
|
M->getFunctionList().push_back(FreeFunc);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ bool LowerAllocations::doInitialization(Module *M) {
|
|||||||
//
|
//
|
||||||
bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
|
bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
assert(MallocMeth && FreeMeth && BB && "Pass not initialized!");
|
assert(MallocFunc && FreeFunc && BB && "Pass not initialized!");
|
||||||
|
|
||||||
// Loop over all of the instructions, looking for malloc or free instructions
|
// Loop over all of the instructions, looking for malloc or free instructions
|
||||||
for (unsigned i = 0; i < BB->size(); ++i) {
|
for (unsigned i = 0; i < BB->size(); ++i) {
|
||||||
@ -136,7 +137,7 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the call to Malloc...
|
// Create the call to Malloc...
|
||||||
CallInst *MCall = new CallInst(MallocMeth,
|
CallInst *MCall = new CallInst(MallocFunc,
|
||||||
vector<Value*>(1, MallocArg));
|
vector<Value*>(1, MallocArg));
|
||||||
BBIL.insert(BBIL.begin()+i, MCall);
|
BBIL.insert(BBIL.begin()+i, MCall);
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock *BB) {
|
|||||||
BBIL.insert(BBIL.begin()+i, MCast);
|
BBIL.insert(BBIL.begin()+i, MCast);
|
||||||
|
|
||||||
// Insert a call to the free function...
|
// Insert a call to the free function...
|
||||||
CallInst *FCall = new CallInst(FreeMeth,
|
CallInst *FCall = new CallInst(FreeFunc,
|
||||||
vector<Value*>(1, MCast));
|
vector<Value*>(1, MCast));
|
||||||
BBIL.insert(BBIL.begin()+i+1, FCall);
|
BBIL.insert(BBIL.begin()+i+1, FCall);
|
||||||
|
|
||||||
@ -185,16 +186,16 @@ bool RaiseAllocations::doInitialization(Module *M) {
|
|||||||
const PointerType *MallocType = // Get the type for malloc
|
const PointerType *MallocType = // Get the type for malloc
|
||||||
PointerType::get(MethodType::get(PointerType::get(Type::SByteTy),
|
PointerType::get(MethodType::get(PointerType::get(Type::SByteTy),
|
||||||
vector<const Type*>(1, Type::UIntTy), false));
|
vector<const Type*>(1, Type::UIntTy), false));
|
||||||
MallocMeth = cast_or_null<Method>(ST->lookup(MallocType, "malloc"));
|
MallocFunc = cast_or_null<Function>(ST->lookup(MallocType, "malloc"));
|
||||||
if (MallocMeth && !MallocMeth->isExternal())
|
if (MallocFunc && !MallocFunc->isExternal())
|
||||||
MallocMeth = 0; // Don't mess with locally defined versions of the fn
|
MallocFunc = 0; // Don't mess with locally defined versions of the fn
|
||||||
|
|
||||||
const PointerType *FreeType = // Get the type for free
|
const PointerType *FreeType = // Get the type for free
|
||||||
PointerType::get(MethodType::get(Type::VoidTy,
|
PointerType::get(MethodType::get(Type::VoidTy,
|
||||||
vector<const Type*>(1, PointerType::get(Type::SByteTy)), false));
|
vector<const Type*>(1, PointerType::get(Type::SByteTy)), false));
|
||||||
FreeMeth = cast_or_null<Method>(ST->lookup(FreeType, "free"));
|
FreeFunc = cast_or_null<Function>(ST->lookup(FreeType, "free"));
|
||||||
if (FreeMeth && !FreeMeth->isExternal())
|
if (FreeFunc && !FreeFunc->isExternal())
|
||||||
FreeMeth = 0; // Don't mess with locally defined versions of the fn
|
FreeFunc = 0; // Don't mess with locally defined versions of the fn
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -209,7 +210,7 @@ bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
|
|||||||
Instruction *I = *BI;
|
Instruction *I = *BI;
|
||||||
|
|
||||||
if (CallInst *CI = dyn_cast<CallInst>(I)) {
|
if (CallInst *CI = dyn_cast<CallInst>(I)) {
|
||||||
if (CI->getCalledValue() == MallocMeth) { // Replace call to malloc?
|
if (CI->getCalledValue() == MallocFunc) { // Replace call to malloc?
|
||||||
const Type *PtrSByte = PointerType::get(Type::SByteTy);
|
const Type *PtrSByte = PointerType::get(Type::SByteTy);
|
||||||
MallocInst *MallocI = new MallocInst(PtrSByte, CI->getOperand(1),
|
MallocInst *MallocI = new MallocInst(PtrSByte, CI->getOperand(1),
|
||||||
CI->getName());
|
CI->getName());
|
||||||
@ -217,7 +218,7 @@ bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
|
|||||||
ReplaceInstWithInst(BIL, BI, MallocI);
|
ReplaceInstWithInst(BIL, BI, MallocI);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
continue; // Skip the ++BI
|
continue; // Skip the ++BI
|
||||||
} else if (CI->getCalledValue() == FreeMeth) { // Replace call to free?
|
} else if (CI->getCalledValue() == FreeFunc) { // Replace call to free?
|
||||||
ReplaceInstWithInst(BIL, BI, new FreeInst(CI->getOperand(1)));
|
ReplaceInstWithInst(BIL, BI, new FreeInst(CI->getOperand(1)));
|
||||||
Changed = true;
|
Changed = true;
|
||||||
continue; // Skip the ++BI
|
continue; // Skip the ++BI
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "llvm/Assembly/CachedWriter.h"
|
#include "llvm/Assembly/CachedWriter.h"
|
||||||
#include "llvm/Analysis/SlotCalculator.h"
|
#include "llvm/Analysis/SlotCalculator.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/ConstantVals.h"
|
#include "llvm/ConstantVals.h"
|
||||||
@ -32,14 +32,14 @@ using std::vector;
|
|||||||
using std::ostream;
|
using std::ostream;
|
||||||
|
|
||||||
static const Module *getModuleFromVal(const Value *V) {
|
static const Module *getModuleFromVal(const Value *V) {
|
||||||
if (const MethodArgument *MA =dyn_cast<const MethodArgument>(V))
|
if (const FunctionArgument *MA = dyn_cast<const FunctionArgument>(V))
|
||||||
return MA->getParent() ? MA->getParent()->getParent() : 0;
|
return MA->getParent() ? MA->getParent()->getParent() : 0;
|
||||||
else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V))
|
else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V))
|
||||||
return BB->getParent() ? BB->getParent()->getParent() : 0;
|
return BB->getParent() ? BB->getParent()->getParent() : 0;
|
||||||
else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
|
else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
|
||||||
const Method *M = I->getParent() ? I->getParent()->getParent() : 0;
|
const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
|
||||||
return M ? M->getParent() : 0;
|
return M ? M->getParent() : 0;
|
||||||
} else if (const GlobalValue *GV =dyn_cast<const GlobalValue>(V))
|
} else if (const GlobalValue *GV = dyn_cast<const GlobalValue>(V))
|
||||||
return GV->getParent();
|
return GV->getParent();
|
||||||
else if (const Module *Mod = dyn_cast<const Module>(V))
|
else if (const Module *Mod = dyn_cast<const Module>(V))
|
||||||
return Mod;
|
return Mod;
|
||||||
@ -48,16 +48,16 @@ static const Module *getModuleFromVal(const Value *V) {
|
|||||||
|
|
||||||
static SlotCalculator *createSlotCalculator(const Value *V) {
|
static SlotCalculator *createSlotCalculator(const Value *V) {
|
||||||
assert(!isa<Type>(V) && "Can't create an SC for a type!");
|
assert(!isa<Type>(V) && "Can't create an SC for a type!");
|
||||||
if (const MethodArgument *MA =dyn_cast<const MethodArgument>(V)){
|
if (const FunctionArgument *FA = dyn_cast<const FunctionArgument>(V)) {
|
||||||
return new SlotCalculator(MA->getParent(), true);
|
return new SlotCalculator(FA->getParent(), true);
|
||||||
} else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
|
} else if (const Instruction *I = dyn_cast<const Instruction>(V)) {
|
||||||
return new SlotCalculator(I->getParent()->getParent(), true);
|
return new SlotCalculator(I->getParent()->getParent(), true);
|
||||||
} else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V)) {
|
} else if (const BasicBlock *BB = dyn_cast<const BasicBlock>(V)) {
|
||||||
return new SlotCalculator(BB->getParent(), true);
|
return new SlotCalculator(BB->getParent(), true);
|
||||||
} else if (const GlobalVariable *GV =dyn_cast<const GlobalVariable>(V)){
|
} else if (const GlobalVariable *GV = dyn_cast<const GlobalVariable>(V)){
|
||||||
return new SlotCalculator(GV->getParent(), true);
|
return new SlotCalculator(GV->getParent(), true);
|
||||||
} else if (const Method *Meth = dyn_cast<const Method>(V)) {
|
} else if (const Function *Func = dyn_cast<const Function>(V)) {
|
||||||
return new SlotCalculator(Meth, true);
|
return new SlotCalculator(Func, true);
|
||||||
} else if (const Module *Mod = dyn_cast<const Module>(V)) {
|
} else if (const Module *Mod = dyn_cast<const Module>(V)) {
|
||||||
return new SlotCalculator(Mod, true);
|
return new SlotCalculator(Mod, true);
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ public:
|
|||||||
|
|
||||||
inline void write(const Module *M) { printModule(M); }
|
inline void write(const Module *M) { printModule(M); }
|
||||||
inline void write(const GlobalVariable *G) { printGlobal(G); }
|
inline void write(const GlobalVariable *G) { printGlobal(G); }
|
||||||
inline void write(const Method *M) { printMethod(M); }
|
inline void write(const Function *F) { printFunction(F); }
|
||||||
inline void write(const BasicBlock *BB) { printBasicBlock(BB); }
|
inline void write(const BasicBlock *BB) { printBasicBlock(BB); }
|
||||||
inline void write(const Instruction *I) { printInstruction(I); }
|
inline void write(const Instruction *I) { printInstruction(I); }
|
||||||
inline void write(const Constant *CPV) { printConstant(CPV); }
|
inline void write(const Constant *CPV) { printConstant(CPV); }
|
||||||
@ -287,8 +287,8 @@ private :
|
|||||||
void printSymbolTable(const SymbolTable &ST);
|
void printSymbolTable(const SymbolTable &ST);
|
||||||
void printConstant(const Constant *CPV);
|
void printConstant(const Constant *CPV);
|
||||||
void printGlobal(const GlobalVariable *GV);
|
void printGlobal(const GlobalVariable *GV);
|
||||||
void printMethod(const Method *M);
|
void printFunction(const Function *F);
|
||||||
void printMethodArgument(const MethodArgument *MA);
|
void printFunctionArgument(const FunctionArgument *FA);
|
||||||
void printBasicBlock(const BasicBlock *BB);
|
void printBasicBlock(const BasicBlock *BB);
|
||||||
void printInstruction(const Instruction *I);
|
void printInstruction(const Instruction *I);
|
||||||
ostream &printType(const Type *Ty);
|
ostream &printType(const Type *Ty);
|
||||||
@ -319,7 +319,7 @@ void AssemblyWriter::printModule(const Module *M) {
|
|||||||
Out << "implementation\n";
|
Out << "implementation\n";
|
||||||
|
|
||||||
// Output all of the methods...
|
// Output all of the methods...
|
||||||
for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::printMethod));
|
for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::printFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||||
@ -385,9 +385,9 @@ void AssemblyWriter::printConstant(const Constant *CPV) {
|
|||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// printMethod - Print all aspects of a method.
|
// printFunction - Print all aspects of a method.
|
||||||
//
|
//
|
||||||
void AssemblyWriter::printMethod(const Method *M) {
|
void AssemblyWriter::printFunction(const Function *M) {
|
||||||
// Print out the return type and name...
|
// Print out the return type and name...
|
||||||
Out << "\n" << (M->isExternal() ? "declare " : "")
|
Out << "\n" << (M->isExternal() ? "declare " : "")
|
||||||
<< (M->hasInternalLinkage() ? "internal " : "");
|
<< (M->hasInternalLinkage() ? "internal " : "");
|
||||||
@ -399,7 +399,7 @@ void AssemblyWriter::printMethod(const Method *M) {
|
|||||||
|
|
||||||
if (!M->isExternal()) {
|
if (!M->isExternal()) {
|
||||||
for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
|
for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
|
||||||
bind_obj(this, &AssemblyWriter::printMethodArgument));
|
bind_obj(this, &AssemblyWriter::printFunctionArgument));
|
||||||
} else {
|
} else {
|
||||||
// Loop over the arguments, printing them...
|
// Loop over the arguments, printing them...
|
||||||
const MethodType *MT = cast<const MethodType>(M->getMethodType());
|
const MethodType *MT = cast<const MethodType>(M->getMethodType());
|
||||||
@ -434,10 +434,10 @@ void AssemblyWriter::printMethod(const Method *M) {
|
|||||||
Table.purgeMethod();
|
Table.purgeMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
// printMethodArgument - This member is called for every argument that
|
// printFunctionArgument - This member is called for every argument that
|
||||||
// is passed into the method. Simply print it out
|
// is passed into the method. Simply print it out
|
||||||
//
|
//
|
||||||
void AssemblyWriter::printMethodArgument(const MethodArgument *Arg) {
|
void AssemblyWriter::printFunctionArgument(const FunctionArgument *Arg) {
|
||||||
// Insert commas as we go... the first arg doesn't get a comma
|
// Insert commas as we go... the first arg doesn't get a comma
|
||||||
if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
|
if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
|
||||||
|
|
||||||
@ -651,12 +651,12 @@ void WriteToAssembly(const GlobalVariable *G, ostream &o) {
|
|||||||
W.write(G);
|
W.write(G);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteToAssembly(const Method *M, ostream &o) {
|
void WriteToAssembly(const Function *F, ostream &o) {
|
||||||
if (M == 0) { o << "<null> method\n"; return; }
|
if (F == 0) { o << "<null> function\n"; return; }
|
||||||
SlotCalculator SlotTable(M->getParent(), true);
|
SlotCalculator SlotTable(F->getParent(), true);
|
||||||
AssemblyWriter W(o, SlotTable, M->getParent());
|
AssemblyWriter W(o, SlotTable, F->getParent());
|
||||||
|
|
||||||
W.write(M);
|
W.write(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -678,9 +678,9 @@ void WriteToAssembly(const Constant *CPV, ostream &o) {
|
|||||||
void WriteToAssembly(const Instruction *I, ostream &o) {
|
void WriteToAssembly(const Instruction *I, ostream &o) {
|
||||||
if (I == 0) { o << "<null> instruction\n"; return; }
|
if (I == 0) { o << "<null> instruction\n"; return; }
|
||||||
|
|
||||||
const Method *M = I->getParent() ? I->getParent()->getParent() : 0;
|
const Function *F = I->getParent() ? I->getParent()->getParent() : 0;
|
||||||
SlotCalculator SlotTable(M, true);
|
SlotCalculator SlotTable(F, true);
|
||||||
AssemblyWriter W(o, SlotTable, M ? M->getParent() : 0);
|
AssemblyWriter W(o, SlotTable, F ? F->getParent() : 0);
|
||||||
|
|
||||||
W.write(I);
|
W.write(I);
|
||||||
}
|
}
|
||||||
@ -706,12 +706,12 @@ CachedWriter &CachedWriter::operator<<(const Value *V) {
|
|||||||
case Value::ConstantVal:
|
case Value::ConstantVal:
|
||||||
Out << " "; AW->write(V->getType());
|
Out << " "; AW->write(V->getType());
|
||||||
Out << " " << cast<Constant>(V)->getStrValue(); break;
|
Out << " " << cast<Constant>(V)->getStrValue(); break;
|
||||||
case Value::MethodArgumentVal:
|
case Value::FunctionArgumentVal:
|
||||||
AW->write(V->getType()); Out << " " << V->getName(); break;
|
AW->write(V->getType()); Out << " " << V->getName(); break;
|
||||||
case Value::TypeVal: AW->write(cast<const Type>(V)); break;
|
case Value::TypeVal: AW->write(cast<const Type>(V)); break;
|
||||||
case Value::InstructionVal: AW->write(cast<Instruction>(V)); break;
|
case Value::InstructionVal: AW->write(cast<Instruction>(V)); break;
|
||||||
case Value::BasicBlockVal: AW->write(cast<BasicBlock>(V)); break;
|
case Value::BasicBlockVal: AW->write(cast<BasicBlock>(V)); break;
|
||||||
case Value::MethodVal: AW->write(cast<Method>(V)); break;
|
case Value::FunctionVal: AW->write(cast<Function>(V)); break;
|
||||||
case Value::GlobalVariableVal: AW->write(cast<GlobalVariable>(V)); break;
|
case Value::GlobalVariableVal: AW->write(cast<GlobalVariable>(V)); break;
|
||||||
case Value::ModuleVal: AW->write(cast<Module>(V)); break;
|
case Value::ModuleVal: AW->write(cast<Module>(V)); break;
|
||||||
default: Out << "<unknown value type: " << V->getValueType() << ">"; break;
|
default: Out << "<unknown value type: " << V->getValueType() << ">"; break;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//===-- Method.cpp - Implement the Method class ------------------*- C++ -*--=//
|
//===-- Function.cpp - Implement the Global object classes -------*- C++ -*--=//
|
||||||
//
|
//
|
||||||
// This file implements the Method & GlobalVariable classes for the VMCore
|
// This file implements the Function & GlobalVariable classes for the VMCore
|
||||||
// library.
|
// library.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -9,27 +9,27 @@
|
|||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/iOther.h"
|
#include "llvm/iOther.h"
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Method Implementation
|
// Function Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
|
||||||
// Instantiate Templates - This ugliness is the price we have to pay
|
// Instantiate Templates - This ugliness is the price we have to pay
|
||||||
// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
|
// for having a ValueHolderImpl.h file seperate from ValueHolder.h! :(
|
||||||
//
|
//
|
||||||
template class ValueHolder<MethodArgument, Method, Method>;
|
template class ValueHolder<FunctionArgument, Function, Function>;
|
||||||
template class ValueHolder<BasicBlock , Method, Method>;
|
template class ValueHolder<BasicBlock , Function, Function>;
|
||||||
|
|
||||||
Function::Function(const MethodType *Ty, bool isInternal,
|
Function::Function(const MethodType *Ty, bool isInternal,
|
||||||
const std::string &name)
|
const std::string &name)
|
||||||
: GlobalValue(PointerType::get(Ty), Value::MethodVal, isInternal, name),
|
: GlobalValue(PointerType::get(Ty), Value::FunctionVal, isInternal, name),
|
||||||
SymTabValue(this), BasicBlocks(this), ArgumentList(this, this) {
|
SymTabValue(this), BasicBlocks(this), ArgumentList(this, this) {
|
||||||
assert(::isa<MethodType>(Ty) && "Method signature must be of method type!");
|
assert(::isa<MethodType>(Ty) && "Function signature must be of method type!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Function::~Function() {
|
Function::~Function() {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "llvm/iOther.h"
|
#include "llvm/iOther.h"
|
||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
#include <algorithm> // find
|
#include <algorithm> // find
|
||||||
@ -27,12 +27,12 @@ TerminatorInst::TerminatorInst(const Type *Ty, Instruction::TermOps iType,
|
|||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// MethodArgument Class
|
// FunctionArgument Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Specialize setName to take care of symbol table majik
|
// Specialize setName to take care of symbol table majik
|
||||||
void MethodArgument::setName(const std::string &name, SymbolTable *ST) {
|
void FunctionArgument::setName(const std::string &name, SymbolTable *ST) {
|
||||||
Method *P;
|
Function *P;
|
||||||
assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) &&
|
assert((ST == 0 || (!getParent() || ST == getParent()->getSymbolTable())) &&
|
||||||
"Invalid symtab argument!");
|
"Invalid symtab argument!");
|
||||||
if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
|
if ((P = getParent()) && hasName()) P->getSymbolTable()->remove(this);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "llvm/Transforms/Linker.h"
|
#include "llvm/Transforms/Linker.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/SymbolTable.h"
|
#include "llvm/SymbolTable.h"
|
||||||
@ -165,8 +165,8 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
|
|||||||
(V = ST->lookup(SGV->getType(), SGV->getName())) &&
|
(V = ST->lookup(SGV->getType(), SGV->getName())) &&
|
||||||
cast<GlobalVariable>(V)->hasExternalLinkage()) {
|
cast<GlobalVariable>(V)->hasExternalLinkage()) {
|
||||||
// The same named thing is a global variable, because the only two things
|
// The same named thing is a global variable, because the only two things
|
||||||
// that may be in a module level symbol table are Global Vars and Methods,
|
// that may be in a module level symbol table are Global Vars and
|
||||||
// and they both have distinct, nonoverlapping, possible types.
|
// Functions, and they both have distinct, nonoverlapping, possible types.
|
||||||
//
|
//
|
||||||
GlobalVariable *DGV = cast<GlobalVariable>(V);
|
GlobalVariable *DGV = cast<GlobalVariable>(V);
|
||||||
|
|
||||||
@ -231,13 +231,13 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkMethodProtos - Link the methods together between the two modules, without
|
// LinkFunctionProtos - Link the functions together between the two modules,
|
||||||
// doing method bodies... this just adds external method prototypes to the Dest
|
// without doing method bodies... this just adds external method prototypes to
|
||||||
// method...
|
// the Dest function...
|
||||||
//
|
//
|
||||||
static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
static bool LinkFunctionProtos(Module *Dest, const Module *Src,
|
||||||
map<const Value*, Value*> &ValueMap,
|
map<const Value*, Value*> &ValueMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
// We will need a module level symbol table if the src module has a module
|
// We will need a module level symbol table if the src module has a module
|
||||||
// level symbol table...
|
// level symbol table...
|
||||||
SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0;
|
SymbolTable *ST = Src->getSymbolTable() ? Dest->getSymbolTableSure() : 0;
|
||||||
@ -245,7 +245,7 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
// Loop over all of the methods in the src module, mapping them over as we go
|
// Loop over all of the methods in the src module, mapping them over as we go
|
||||||
//
|
//
|
||||||
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const Method *SM = *I; // SrcMethod
|
const Function *SM = *I; // SrcFunction
|
||||||
Value *V;
|
Value *V;
|
||||||
|
|
||||||
// If the method has a name, and that name is already in use in the
|
// If the method has a name, and that name is already in use in the
|
||||||
@ -253,29 +253,29 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
//
|
//
|
||||||
if (SM->hasExternalLinkage() && SM->hasName() &&
|
if (SM->hasExternalLinkage() && SM->hasName() &&
|
||||||
(V = ST->lookup(SM->getType(), SM->getName())) &&
|
(V = ST->lookup(SM->getType(), SM->getName())) &&
|
||||||
cast<Method>(V)->hasExternalLinkage()) {
|
cast<Function>(V)->hasExternalLinkage()) {
|
||||||
// The same named thing is a Method, because the only two things
|
// The same named thing is a Function, because the only two things
|
||||||
// that may be in a module level symbol table are Global Vars and Methods,
|
// that may be in a module level symbol table are Global Vars and
|
||||||
// and they both have distinct, nonoverlapping, possible types.
|
// Functions, and they both have distinct, nonoverlapping, possible types.
|
||||||
//
|
//
|
||||||
Method *DM = cast<Method>(V); // DestMethod
|
Function *DM = cast<Function>(V); // DestFunction
|
||||||
|
|
||||||
// Check to make sure the method is not defined in both modules...
|
// Check to make sure the method is not defined in both modules...
|
||||||
if (!SM->isExternal() && !DM->isExternal())
|
if (!SM->isExternal() && !DM->isExternal())
|
||||||
return Error(Err, "Method '" +
|
return Error(Err, "Function '" +
|
||||||
SM->getMethodType()->getDescription() + "':\"" +
|
SM->getMethodType()->getDescription() + "':\"" +
|
||||||
SM->getName() + "\" - Method is already defined!");
|
SM->getName() + "\" - Function is already defined!");
|
||||||
|
|
||||||
// Otherwise, just remember this mapping...
|
// Otherwise, just remember this mapping...
|
||||||
ValueMap.insert(std::make_pair(SM, DM));
|
ValueMap.insert(std::make_pair(SM, DM));
|
||||||
} else {
|
} else {
|
||||||
// Method does not already exist, simply insert an external method
|
// Function does not already exist, simply insert an external method
|
||||||
// signature identical to SM into the dest module...
|
// signature identical to SM into the dest module...
|
||||||
Method *DM = new Method(SM->getMethodType(), SM->hasInternalLinkage(),
|
Function *DM = new Function(SM->getMethodType(), SM->hasInternalLinkage(),
|
||||||
SM->getName());
|
SM->getName());
|
||||||
|
|
||||||
// Add the method signature to the dest module...
|
// Add the method signature to the dest module...
|
||||||
Dest->getMethodList().push_back(DM);
|
Dest->getFunctionList().push_back(DM);
|
||||||
|
|
||||||
// ... and remember this mapping...
|
// ... and remember this mapping...
|
||||||
ValueMap.insert(std::make_pair(SM, DM));
|
ValueMap.insert(std::make_pair(SM, DM));
|
||||||
@ -284,24 +284,24 @@ static bool LinkMethodProtos(Module *Dest, const Module *Src,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkMethodBody - Copy the source method over into the dest method and fix up
|
// LinkFunctionBody - Copy the source method over into the dest method
|
||||||
// references to values. At this point we know that Dest is an external method,
|
// and fix up references to values. At this point we know that Dest
|
||||||
// and that Src is not.
|
// is an external method, and that Src is not.
|
||||||
//
|
//
|
||||||
static bool LinkMethodBody(Method *Dest, const Method *Src,
|
static bool LinkFunctionBody(Function *Dest, const Function *Src,
|
||||||
const map<const Value*, Value*> &GlobalMap,
|
const map<const Value*, Value*> &GlobalMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
assert(Src && Dest && Dest->isExternal() && !Src->isExternal());
|
assert(Src && Dest && Dest->isExternal() && !Src->isExternal());
|
||||||
map<const Value*, Value*> LocalMap; // Map for method local values
|
map<const Value*, Value*> LocalMap; // Map for method local values
|
||||||
|
|
||||||
// Go through and convert method arguments over...
|
// Go through and convert method arguments over...
|
||||||
for (Method::ArgumentListType::const_iterator
|
for (Function::ArgumentListType::const_iterator
|
||||||
I = Src->getArgumentList().begin(),
|
I = Src->getArgumentList().begin(),
|
||||||
E = Src->getArgumentList().end(); I != E; ++I) {
|
E = Src->getArgumentList().end(); I != E; ++I) {
|
||||||
const MethodArgument *SMA = *I;
|
const FunctionArgument *SMA = *I;
|
||||||
|
|
||||||
// Create the new method argument and add to the dest method...
|
// Create the new method argument and add to the dest method...
|
||||||
MethodArgument *DMA = new MethodArgument(SMA->getType(), SMA->getName());
|
FunctionArgument *DMA = new FunctionArgument(SMA->getType(),SMA->getName());
|
||||||
Dest->getArgumentList().push_back(DMA);
|
Dest->getArgumentList().push_back(DMA);
|
||||||
|
|
||||||
// Add a mapping to our local map
|
// Add a mapping to our local map
|
||||||
@ -310,7 +310,7 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
|
|
||||||
// Loop over all of the basic blocks, copying the instructions over...
|
// Loop over all of the basic blocks, copying the instructions over...
|
||||||
//
|
//
|
||||||
for (Method::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Function::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const BasicBlock *SBB = *I;
|
const BasicBlock *SBB = *I;
|
||||||
|
|
||||||
// Create new basic block and add to mapping and the Dest method...
|
// Create new basic block and add to mapping and the Dest method...
|
||||||
@ -338,7 +338,7 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
// in the Source method as operands. Loop through all of the operands of the
|
// in the Source method as operands. Loop through all of the operands of the
|
||||||
// methods and patch them up to point to the local versions...
|
// methods and patch them up to point to the local versions...
|
||||||
//
|
//
|
||||||
for (Method::iterator BI = Dest->begin(), BE = Dest->end();
|
for (Function::iterator BI = Dest->begin(), BE = Dest->end();
|
||||||
BI != BE; ++BI) {
|
BI != BE; ++BI) {
|
||||||
BasicBlock *BB = *BI;
|
BasicBlock *BB = *BI;
|
||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||||
@ -354,30 +354,30 @@ static bool LinkMethodBody(Method *Dest, const Method *Src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// LinkMethodBodies - Link in the method bodies that are defined in the source
|
// LinkFunctionBodies - Link in the method bodies that are defined in the source
|
||||||
// module into the DestModule. This consists basically of copying the method
|
// module into the DestModule. This consists basically of copying the method
|
||||||
// over and fixing up references to values.
|
// over and fixing up references to values.
|
||||||
//
|
//
|
||||||
static bool LinkMethodBodies(Module *Dest, const Module *Src,
|
static bool LinkFunctionBodies(Module *Dest, const Module *Src,
|
||||||
map<const Value*, Value*> &ValueMap,
|
map<const Value*, Value*> &ValueMap,
|
||||||
string *Err = 0) {
|
string *Err = 0) {
|
||||||
|
|
||||||
// Loop over all of the methods in the src module, mapping them over as we go
|
// Loop over all of the methods in the src module, mapping them over as we go
|
||||||
//
|
//
|
||||||
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) {
|
||||||
const Method *SM = *I; // Source Method
|
const Function *SM = *I; // Source Function
|
||||||
if (!SM->isExternal()) { // No body if method is external
|
if (!SM->isExternal()) { // No body if method is external
|
||||||
Method *DM = cast<Method>(ValueMap[SM]); // Destination method
|
Function *DM = cast<Function>(ValueMap[SM]); // Destination method
|
||||||
|
|
||||||
// DM not external SM external?
|
// DM not external SM external?
|
||||||
if (!DM->isExternal()) {
|
if (!DM->isExternal()) {
|
||||||
if (Err)
|
if (Err)
|
||||||
*Err = "Method '" + (SM->hasName() ? SM->getName() : string("")) +
|
*Err = "Function '" + (SM->hasName() ? SM->getName() : string("")) +
|
||||||
"' body multiply defined!";
|
"' body multiply defined!";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LinkMethodBody(DM, SM, ValueMap, Err)) return true;
|
if (LinkFunctionBody(DM, SM, ValueMap, Err)) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -418,13 +418,13 @@ bool LinkModules(Module *Dest, const Module *Src, string *ErrorMsg = 0) {
|
|||||||
// We do this so that when we begin processing method bodies, all of the
|
// We do this so that when we begin processing method bodies, all of the
|
||||||
// global values that may be referenced are available in our ValueMap.
|
// global values that may be referenced are available in our ValueMap.
|
||||||
//
|
//
|
||||||
if (LinkMethodProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
|
if (LinkFunctionProtos(Dest, Src, ValueMap, ErrorMsg)) return true;
|
||||||
|
|
||||||
// Link in the method bodies that are defined in the source module into the
|
// Link in the method bodies that are defined in the source module into the
|
||||||
// DestModule. This consists basically of copying the method over and fixing
|
// DestModule. This consists basically of copying the method over and fixing
|
||||||
// up references to values.
|
// up references to values.
|
||||||
//
|
//
|
||||||
if (LinkMethodBodies(Dest, Src, ValueMap, ErrorMsg)) return true;
|
if (LinkFunctionBodies(Dest, Src, ValueMap, ErrorMsg)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/InstrTypes.h"
|
#include "llvm/InstrTypes.h"
|
||||||
#include "llvm/ValueHolderImpl.h"
|
#include "llvm/ValueHolderImpl.h"
|
||||||
@ -18,7 +18,7 @@
|
|||||||
// for having a DefHolderImpl.h file seperate from DefHolder.h! :(
|
// for having a DefHolderImpl.h file seperate from DefHolder.h! :(
|
||||||
//
|
//
|
||||||
template class ValueHolder<GlobalVariable, Module, Module>;
|
template class ValueHolder<GlobalVariable, Module, Module>;
|
||||||
template class ValueHolder<Method, Module, Module>;
|
template class ValueHolder<Function, Module, Module>;
|
||||||
|
|
||||||
// Define the GlobalValueRefMap as a struct that wraps a map so that we don't
|
// Define the GlobalValueRefMap as a struct that wraps a map so that we don't
|
||||||
// have Module.h depend on <map>
|
// have Module.h depend on <map>
|
||||||
@ -29,15 +29,15 @@ struct GlobalValueRefMap : public std::map<GlobalValue*, ConstantPointerRef*>{
|
|||||||
|
|
||||||
Module::Module()
|
Module::Module()
|
||||||
: Value(Type::VoidTy, Value::ModuleVal, ""), SymTabValue(this),
|
: Value(Type::VoidTy, Value::ModuleVal, ""), SymTabValue(this),
|
||||||
GlobalList(this, this), MethodList(this, this), GVRefMap(0) {
|
GlobalList(this, this), FunctionList(this, this), GVRefMap(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Module::~Module() {
|
Module::~Module() {
|
||||||
dropAllReferences();
|
dropAllReferences();
|
||||||
GlobalList.delete_all();
|
GlobalList.delete_all();
|
||||||
GlobalList.setParent(0);
|
GlobalList.setParent(0);
|
||||||
MethodList.delete_all();
|
FunctionList.delete_all();
|
||||||
MethodList.setParent(0);
|
FunctionList.setParent(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -50,8 +50,8 @@ Module::~Module() {
|
|||||||
// delete.
|
// delete.
|
||||||
//
|
//
|
||||||
void Module::dropAllReferences() {
|
void Module::dropAllReferences() {
|
||||||
for_each(MethodList.begin(), MethodList.end(),
|
for_each(FunctionList.begin(), FunctionList.end(),
|
||||||
std::mem_fun(&Method::dropAllReferences));
|
std::mem_fun(&Function::dropAllReferences));
|
||||||
|
|
||||||
for_each(GlobalList.begin(), GlobalList.end(),
|
for_each(GlobalList.begin(), GlobalList.end(),
|
||||||
std::mem_fun(&GlobalVariable::dropAllReferences));
|
std::mem_fun(&GlobalVariable::dropAllReferences));
|
||||||
@ -80,10 +80,10 @@ bool Module::reduceApply(bool (*Func)(GlobalVariable*)) {
|
|||||||
bool Module::reduceApply(bool (*Func)(const GlobalVariable*)) const {
|
bool Module::reduceApply(bool (*Func)(const GlobalVariable*)) const {
|
||||||
return reduce_apply_bool(gbegin(), gend(), Func);
|
return reduce_apply_bool(gbegin(), gend(), Func);
|
||||||
}
|
}
|
||||||
bool Module::reduceApply(bool (*Func)(Method*)) {
|
bool Module::reduceApply(bool (*Func)(Function*)) {
|
||||||
return reduce_apply_bool(begin(), end(), Func);
|
return reduce_apply_bool(begin(), end(), Func);
|
||||||
}
|
}
|
||||||
bool Module::reduceApply(bool (*Func)(const Method*)) const {
|
bool Module::reduceApply(bool (*Func)(const Function*)) const {
|
||||||
return reduce_apply_bool(begin(), end(), Func);
|
return reduce_apply_bool(begin(), end(), Func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "llvm/PassManager.h"
|
#include "llvm/PassManager.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "llvm/BasicBlock.h"
|
#include "llvm/BasicBlock.h"
|
||||||
#include "Support/STLExtras.h"
|
#include "Support/STLExtras.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -59,8 +59,8 @@ void PMDebug::PrintPassInformation(unsigned Depth, const char *Action,
|
|||||||
switch (V->getValueType()) {
|
switch (V->getValueType()) {
|
||||||
case Value::ModuleVal:
|
case Value::ModuleVal:
|
||||||
std::cerr << "Module\n"; return;
|
std::cerr << "Module\n"; return;
|
||||||
case Value::MethodVal:
|
case Value::FunctionVal:
|
||||||
std::cerr << "Method '" << V->getName(); break;
|
std::cerr << "Function '" << V->getName(); break;
|
||||||
case Value::BasicBlockVal:
|
case Value::BasicBlockVal:
|
||||||
std::cerr << "BasicBlock '" << V->getName(); break;
|
std::cerr << "BasicBlock '" << V->getName(); break;
|
||||||
default:
|
default:
|
||||||
@ -119,11 +119,11 @@ bool MethodPass::run(Module *M) {
|
|||||||
|
|
||||||
// run - On a method, we simply initialize, run the method, then finalize.
|
// run - On a method, we simply initialize, run the method, then finalize.
|
||||||
//
|
//
|
||||||
bool MethodPass::run(Method *M) {
|
bool MethodPass::run(Function *F) {
|
||||||
if (M->isExternal()) return false; // Passes are not run on external methods!
|
if (F->isExternal()) return false; // Passes are not run on external methods!
|
||||||
|
|
||||||
return doInitialization(M->getParent()) | runOnMethod(M)
|
return doInitialization(F->getParent()) | runOnMethod(F)
|
||||||
| doFinalization(M->getParent());
|
| doFinalization(F->getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodPass::addToPassManager(PassManagerT<Module> *PM,
|
void MethodPass::addToPassManager(PassManagerT<Module> *PM,
|
||||||
@ -132,7 +132,7 @@ void MethodPass::addToPassManager(PassManagerT<Module> *PM,
|
|||||||
PM->addPass(this, Required, Destroyed, Provided);
|
PM->addPass(this, Required, Destroyed, Provided);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodPass::addToPassManager(PassManagerT<Method> *PM,
|
void MethodPass::addToPassManager(PassManagerT<Function> *PM,
|
||||||
AnalysisSet &Required, AnalysisSet &Destroyed,
|
AnalysisSet &Required, AnalysisSet &Destroyed,
|
||||||
AnalysisSet &Provided) {
|
AnalysisSet &Provided) {
|
||||||
PM->addPass(this, Required, Destroyed, Provided);
|
PM->addPass(this, Required, Destroyed, Provided);
|
||||||
@ -145,9 +145,9 @@ void MethodPass::addToPassManager(PassManagerT<Method> *PM,
|
|||||||
// To run this pass on a method, we simply call runOnBasicBlock once for each
|
// To run this pass on a method, we simply call runOnBasicBlock once for each
|
||||||
// method.
|
// method.
|
||||||
//
|
//
|
||||||
bool BasicBlockPass::runOnMethod(Method *M) {
|
bool BasicBlockPass::runOnMethod(Function *F) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
for (Method::iterator I = M->begin(), E = M->end(); I != E; ++I)
|
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
|
||||||
Changed |= runOnBasicBlock(*I);
|
Changed |= runOnBasicBlock(*I);
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ bool BasicBlockPass::run(BasicBlock *BB) {
|
|||||||
return doInitialization(M) | runOnBasicBlock(BB) | doFinalization(M);
|
return doInitialization(M) | runOnBasicBlock(BB) | doFinalization(M);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicBlockPass::addToPassManager(PassManagerT<Method> *PM,
|
void BasicBlockPass::addToPassManager(PassManagerT<Function> *PM,
|
||||||
AnalysisSet &Required,
|
AnalysisSet &Required,
|
||||||
AnalysisSet &Destroyed,
|
AnalysisSet &Destroyed,
|
||||||
AnalysisSet &Provided) {
|
AnalysisSet &Provided) {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "llvm/InstrTypes.h"
|
#include "llvm/InstrTypes.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Method.h"
|
#include "llvm/Function.h"
|
||||||
#include "Support/StringExtras.h"
|
#include "Support/StringExtras.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -238,8 +238,8 @@ void SymbolTable::refineAbstractType(const DerivedType *OldType,
|
|||||||
// The only thing we are allowing for now is two method prototypes being
|
// The only thing we are allowing for now is two method prototypes being
|
||||||
// folded into one.
|
// folded into one.
|
||||||
//
|
//
|
||||||
Method *ExistM = dyn_cast<Method>(TI->second);
|
Function *ExistM = dyn_cast<Function>(TI->second);
|
||||||
Method *NewM = dyn_cast<Method>(V.second);
|
Function *NewM = dyn_cast<Function>(V.second);
|
||||||
|
|
||||||
if (ExistM && NewM && ExistM->isExternal() && NewM->isExternal()) {
|
if (ExistM && NewM && ExistM->isExternal() && NewM->isExternal()) {
|
||||||
// Ok we have two external methods. Make all uses of the new one
|
// Ok we have two external methods. Make all uses of the new one
|
||||||
@ -264,7 +264,7 @@ void SymbolTable::refineAbstractType(const DerivedType *OldType,
|
|||||||
InternallyInconsistent = false;
|
InternallyInconsistent = false;
|
||||||
|
|
||||||
// Now we can remove this method from the module entirely...
|
// Now we can remove this method from the module entirely...
|
||||||
NewM->getParent()->getMethodList().remove(NewM);
|
NewM->getParent()->getFunctionList().remove(NewM);
|
||||||
delete NewM;
|
delete NewM;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user