mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-28 00:40:54 +00:00
More LLVMContext-ification.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74811 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e8c81ea3f8
commit
14ce9ef2e9
@ -36,6 +36,7 @@
|
|||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/CallGraphSCCPass.h"
|
#include "llvm/CallGraphSCCPass.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Analysis/CallGraph.h"
|
#include "llvm/Analysis/CallGraph.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
@ -585,7 +586,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct the new function type using the new arguments.
|
// Construct the new function type using the new arguments.
|
||||||
FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
|
FunctionType *NFTy = Context->getFunctionType(RetTy, Params, FTy->isVarArg());
|
||||||
|
|
||||||
// Create the new function body and insert it into the module...
|
// Create the new function body and insert it into the module...
|
||||||
Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName());
|
Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName());
|
||||||
@ -636,9 +637,9 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
|||||||
// Emit a GEP and load for each element of the struct.
|
// Emit a GEP and load for each element of the struct.
|
||||||
const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
|
const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
|
||||||
const StructType *STy = cast<StructType>(AgTy);
|
const StructType *STy = cast<StructType>(AgTy);
|
||||||
Value *Idxs[2] = { ConstantInt::get(Type::Int32Ty, 0), 0 };
|
Value *Idxs[2] = { Context->getConstantInt(Type::Int32Ty, 0), 0 };
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
||||||
Idxs[1] = ConstantInt::get(Type::Int32Ty, i);
|
Idxs[1] = Context->getConstantInt(Type::Int32Ty, i);
|
||||||
Value *Idx = GetElementPtrInst::Create(*AI, Idxs, Idxs+2,
|
Value *Idx = GetElementPtrInst::Create(*AI, Idxs, Idxs+2,
|
||||||
(*AI)->getName()+"."+utostr(i),
|
(*AI)->getName()+"."+utostr(i),
|
||||||
Call);
|
Call);
|
||||||
@ -663,7 +664,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
|||||||
// Use i32 to index structs, and i64 for others (pointers/arrays).
|
// Use i32 to index structs, and i64 for others (pointers/arrays).
|
||||||
// This satisfies GEP constraints.
|
// This satisfies GEP constraints.
|
||||||
const Type *IdxTy = (isa<StructType>(ElTy) ? Type::Int32Ty : Type::Int64Ty);
|
const Type *IdxTy = (isa<StructType>(ElTy) ? Type::Int32Ty : Type::Int64Ty);
|
||||||
Ops.push_back(ConstantInt::get(IdxTy, *II));
|
Ops.push_back(Context->getConstantInt(IdxTy, *II));
|
||||||
// Keep track of the type we're currently indexing
|
// Keep track of the type we're currently indexing
|
||||||
ElTy = cast<CompositeType>(ElTy)->getTypeAtIndex(*II);
|
ElTy = cast<CompositeType>(ElTy)->getTypeAtIndex(*II);
|
||||||
}
|
}
|
||||||
@ -679,7 +680,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ExtraArgHack)
|
if (ExtraArgHack)
|
||||||
Args.push_back(Constant::getNullValue(Type::Int32Ty));
|
Args.push_back(Context->getNullValue(Type::Int32Ty));
|
||||||
|
|
||||||
// Push any varargs arguments on the list
|
// Push any varargs arguments on the list
|
||||||
for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
|
for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
|
||||||
@ -756,10 +757,10 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
|||||||
const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
|
const Type *AgTy = cast<PointerType>(I->getType())->getElementType();
|
||||||
Value *TheAlloca = new AllocaInst(AgTy, 0, "", InsertPt);
|
Value *TheAlloca = new AllocaInst(AgTy, 0, "", InsertPt);
|
||||||
const StructType *STy = cast<StructType>(AgTy);
|
const StructType *STy = cast<StructType>(AgTy);
|
||||||
Value *Idxs[2] = { ConstantInt::get(Type::Int32Ty, 0), 0 };
|
Value *Idxs[2] = { Context->getConstantInt(Type::Int32Ty, 0), 0 };
|
||||||
|
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
||||||
Idxs[1] = ConstantInt::get(Type::Int32Ty, i);
|
Idxs[1] = Context->getConstantInt(Type::Int32Ty, i);
|
||||||
std::string Name = TheAlloca->getName()+"."+utostr(i);
|
std::string Name = TheAlloca->getName()+"."+utostr(i);
|
||||||
Value *Idx = GetElementPtrInst::Create(TheAlloca, Idxs, Idxs+2,
|
Value *Idx = GetElementPtrInst::Create(TheAlloca, Idxs, Idxs+2,
|
||||||
Name, InsertPt);
|
Name, InsertPt);
|
||||||
@ -842,7 +843,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
|||||||
|
|
||||||
// Notify the alias analysis implementation that we inserted a new argument.
|
// Notify the alias analysis implementation that we inserted a new argument.
|
||||||
if (ExtraArgHack)
|
if (ExtraArgHack)
|
||||||
AA.copyValue(Constant::getNullValue(Type::Int32Ty), NF->arg_begin());
|
AA.copyValue(Context->getNullValue(Type::Int32Ty), NF->arg_begin());
|
||||||
|
|
||||||
|
|
||||||
// Tell the alias analysis that the old function is about to disappear.
|
// Tell the alias analysis that the old function is about to disappear.
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/IntrinsicInst.h"
|
#include "llvm/IntrinsicInst.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
@ -196,7 +197,8 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
|
|||||||
// the old function, but doesn't have isVarArg set.
|
// the old function, but doesn't have isVarArg set.
|
||||||
const FunctionType *FTy = Fn.getFunctionType();
|
const FunctionType *FTy = Fn.getFunctionType();
|
||||||
std::vector<const Type*> Params(FTy->param_begin(), FTy->param_end());
|
std::vector<const Type*> Params(FTy->param_begin(), FTy->param_end());
|
||||||
FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, false);
|
FunctionType *NFTy = Context->getFunctionType(FTy->getReturnType(),
|
||||||
|
Params, false);
|
||||||
unsigned NumArgs = Params.size();
|
unsigned NumArgs = Params.size();
|
||||||
|
|
||||||
// Create the new function body and insert it into the module...
|
// Create the new function body and insert it into the module...
|
||||||
@ -633,7 +635,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
// something and {} into void.
|
// something and {} into void.
|
||||||
// Make the new struct packed if we used to return a packed struct
|
// Make the new struct packed if we used to return a packed struct
|
||||||
// already.
|
// already.
|
||||||
NRetTy = StructType::get(RetTypes, STy->isPacked());
|
NRetTy = Context->getStructType(RetTypes, STy->isPacked());
|
||||||
else if (RetTypes.size() == 1)
|
else if (RetTypes.size() == 1)
|
||||||
// One return type? Just a simple value then, but only if we didn't use to
|
// One return type? Just a simple value then, but only if we didn't use to
|
||||||
// return a struct with that simple value before.
|
// return a struct with that simple value before.
|
||||||
@ -701,7 +703,8 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the new function type based on the recomputed parameters.
|
// Create the new function type based on the recomputed parameters.
|
||||||
FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg());
|
FunctionType *NFTy = Context->getFunctionType(NRetTy, Params,
|
||||||
|
FTy->isVarArg());
|
||||||
|
|
||||||
// No change?
|
// No change?
|
||||||
if (NFTy == FTy)
|
if (NFTy == FTy)
|
||||||
@ -750,7 +753,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ExtraArgHack)
|
if (ExtraArgHack)
|
||||||
Args.push_back(UndefValue::get(Type::Int32Ty));
|
Args.push_back(Context->getUndef(Type::Int32Ty));
|
||||||
|
|
||||||
// Push any varargs arguments on the list. Don't forget their attributes.
|
// Push any varargs arguments on the list. Don't forget their attributes.
|
||||||
for (CallSite::arg_iterator E = CS.arg_end(); I != E; ++I, ++i) {
|
for (CallSite::arg_iterator E = CS.arg_end(); I != E; ++I, ++i) {
|
||||||
@ -789,7 +792,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
} else if (New->getType() == Type::VoidTy) {
|
} else if (New->getType() == Type::VoidTy) {
|
||||||
// Our return value has uses, but they will get removed later on.
|
// Our return value has uses, but they will get removed later on.
|
||||||
// Replace by null for now.
|
// Replace by null for now.
|
||||||
Call->replaceAllUsesWith(Constant::getNullValue(Call->getType()));
|
Call->replaceAllUsesWith(Context->getNullValue(Call->getType()));
|
||||||
} else {
|
} else {
|
||||||
assert(isa<StructType>(RetTy) &&
|
assert(isa<StructType>(RetTy) &&
|
||||||
"Return type changed, but not into a void. The old return type"
|
"Return type changed, but not into a void. The old return type"
|
||||||
@ -806,7 +809,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
// extract/insertvalue chaining and let instcombine clean that up.
|
// extract/insertvalue chaining and let instcombine clean that up.
|
||||||
//
|
//
|
||||||
// Start out building up our return value from undef
|
// Start out building up our return value from undef
|
||||||
Value *RetVal = llvm::UndefValue::get(RetTy);
|
Value *RetVal = Context->getUndef(RetTy);
|
||||||
for (unsigned i = 0; i != RetCount; ++i)
|
for (unsigned i = 0; i != RetCount; ++i)
|
||||||
if (NewRetIdxs[i] != -1) {
|
if (NewRetIdxs[i] != -1) {
|
||||||
Value *V;
|
Value *V;
|
||||||
@ -852,7 +855,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
} else {
|
} else {
|
||||||
// If this argument is dead, replace any uses of it with null constants
|
// If this argument is dead, replace any uses of it with null constants
|
||||||
// (these are guaranteed to become unused later on).
|
// (these are guaranteed to become unused later on).
|
||||||
I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
|
I->replaceAllUsesWith(Context->getNullValue(I->getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we change the return value of the function we must rewrite any return
|
// If we change the return value of the function we must rewrite any return
|
||||||
@ -873,7 +876,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
|||||||
// clean that up.
|
// clean that up.
|
||||||
Value *OldRet = RI->getOperand(0);
|
Value *OldRet = RI->getOperand(0);
|
||||||
// Start out building up our return value from undef
|
// Start out building up our return value from undef
|
||||||
RetVal = llvm::UndefValue::get(NRetTy);
|
RetVal = Context->getUndef(NRetTy);
|
||||||
for (unsigned i = 0; i != RetCount; ++i)
|
for (unsigned i = 0; i != RetCount; ++i)
|
||||||
if (NewRetIdxs[i] != -1) {
|
if (NewRetIdxs[i] != -1) {
|
||||||
ExtractValueInst *EV = ExtractValueInst::Create(OldRet, i,
|
ExtractValueInst *EV = ExtractValueInst::Create(OldRet, i,
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
@ -99,14 +100,14 @@ namespace {
|
|||||||
// by putting them in the used array
|
// by putting them in the used array
|
||||||
{
|
{
|
||||||
std::vector<Constant *> AUGs;
|
std::vector<Constant *> AUGs;
|
||||||
const Type *SBP= PointerType::getUnqual(Type::Int8Ty);
|
const Type *SBP= Context->getPointerTypeUnqual(Type::Int8Ty);
|
||||||
for (std::vector<GlobalValue*>::iterator GI = Named.begin(),
|
for (std::vector<GlobalValue*>::iterator GI = Named.begin(),
|
||||||
GE = Named.end(); GI != GE; ++GI) {
|
GE = Named.end(); GI != GE; ++GI) {
|
||||||
(*GI)->setLinkage(GlobalValue::ExternalLinkage);
|
(*GI)->setLinkage(GlobalValue::ExternalLinkage);
|
||||||
AUGs.push_back(ConstantExpr::getBitCast(*GI, SBP));
|
AUGs.push_back(Context->getConstantExprBitCast(*GI, SBP));
|
||||||
}
|
}
|
||||||
ArrayType *AT = ArrayType::get(SBP, AUGs.size());
|
ArrayType *AT = Context->getArrayType(SBP, AUGs.size());
|
||||||
Constant *Init = ConstantArray::get(AT, AUGs);
|
Constant *Init = Context->getConstantArray(AT, AUGs);
|
||||||
GlobalValue *gv = new GlobalVariable(AT, false,
|
GlobalValue *gv = new GlobalVariable(AT, false,
|
||||||
GlobalValue::AppendingLinkage,
|
GlobalValue::AppendingLinkage,
|
||||||
Init, "llvm.used", &M);
|
Init, "llvm.used", &M);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/IntrinsicInst.h"
|
#include "llvm/IntrinsicInst.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Analysis/ConstantFolding.h"
|
#include "llvm/Analysis/ConstantFolding.h"
|
||||||
@ -244,7 +245,8 @@ static bool AnalyzeGlobal(Value *V, GlobalStatus &GS,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Constant *getAggregateConstantElement(Constant *Agg, Constant *Idx) {
|
static Constant *getAggregateConstantElement(Constant *Agg, Constant *Idx,
|
||||||
|
LLVMContext* Context) {
|
||||||
ConstantInt *CI = dyn_cast<ConstantInt>(Idx);
|
ConstantInt *CI = dyn_cast<ConstantInt>(Idx);
|
||||||
if (!CI) return 0;
|
if (!CI) return 0;
|
||||||
unsigned IdxV = CI->getZExtValue();
|
unsigned IdxV = CI->getZExtValue();
|
||||||
@ -258,18 +260,18 @@ static Constant *getAggregateConstantElement(Constant *Agg, Constant *Idx) {
|
|||||||
} else if (isa<ConstantAggregateZero>(Agg)) {
|
} else if (isa<ConstantAggregateZero>(Agg)) {
|
||||||
if (const StructType *STy = dyn_cast<StructType>(Agg->getType())) {
|
if (const StructType *STy = dyn_cast<StructType>(Agg->getType())) {
|
||||||
if (IdxV < STy->getNumElements())
|
if (IdxV < STy->getNumElements())
|
||||||
return Constant::getNullValue(STy->getElementType(IdxV));
|
return Context->getNullValue(STy->getElementType(IdxV));
|
||||||
} else if (const SequentialType *STy =
|
} else if (const SequentialType *STy =
|
||||||
dyn_cast<SequentialType>(Agg->getType())) {
|
dyn_cast<SequentialType>(Agg->getType())) {
|
||||||
return Constant::getNullValue(STy->getElementType());
|
return Context->getNullValue(STy->getElementType());
|
||||||
}
|
}
|
||||||
} else if (isa<UndefValue>(Agg)) {
|
} else if (isa<UndefValue>(Agg)) {
|
||||||
if (const StructType *STy = dyn_cast<StructType>(Agg->getType())) {
|
if (const StructType *STy = dyn_cast<StructType>(Agg->getType())) {
|
||||||
if (IdxV < STy->getNumElements())
|
if (IdxV < STy->getNumElements())
|
||||||
return UndefValue::get(STy->getElementType(IdxV));
|
return Context->getUndef(STy->getElementType(IdxV));
|
||||||
} else if (const SequentialType *STy =
|
} else if (const SequentialType *STy =
|
||||||
dyn_cast<SequentialType>(Agg->getType())) {
|
dyn_cast<SequentialType>(Agg->getType())) {
|
||||||
return UndefValue::get(STy->getElementType());
|
return Context->getUndef(STy->getElementType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -461,7 +463,8 @@ static bool GlobalUsersSafeToSRA(GlobalValue *GV) {
|
|||||||
/// behavior of the program in a more fine-grained way. We have determined that
|
/// behavior of the program in a more fine-grained way. We have determined that
|
||||||
/// this transformation is safe already. We return the first global variable we
|
/// this transformation is safe already. We return the first global variable we
|
||||||
/// insert so that the caller can reprocess it.
|
/// insert so that the caller can reprocess it.
|
||||||
static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) {
|
static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD,
|
||||||
|
LLVMContext* Context) {
|
||||||
// Make sure this global only has simple uses that we can SRA.
|
// Make sure this global only has simple uses that we can SRA.
|
||||||
if (!GlobalUsersSafeToSRA(GV))
|
if (!GlobalUsersSafeToSRA(GV))
|
||||||
return 0;
|
return 0;
|
||||||
@ -483,7 +486,8 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) {
|
|||||||
const StructLayout &Layout = *TD.getStructLayout(STy);
|
const StructLayout &Layout = *TD.getStructLayout(STy);
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
|
||||||
Constant *In = getAggregateConstantElement(Init,
|
Constant *In = getAggregateConstantElement(Init,
|
||||||
ConstantInt::get(Type::Int32Ty, i));
|
Context->getConstantInt(Type::Int32Ty, i),
|
||||||
|
Context);
|
||||||
assert(In && "Couldn't get element of initializer?");
|
assert(In && "Couldn't get element of initializer?");
|
||||||
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(i), false,
|
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(i), false,
|
||||||
GlobalVariable::InternalLinkage,
|
GlobalVariable::InternalLinkage,
|
||||||
@ -517,7 +521,8 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) {
|
|||||||
unsigned EltAlign = TD.getABITypeAlignment(STy->getElementType());
|
unsigned EltAlign = TD.getABITypeAlignment(STy->getElementType());
|
||||||
for (unsigned i = 0, e = NumElements; i != e; ++i) {
|
for (unsigned i = 0, e = NumElements; i != e; ++i) {
|
||||||
Constant *In = getAggregateConstantElement(Init,
|
Constant *In = getAggregateConstantElement(Init,
|
||||||
ConstantInt::get(Type::Int32Ty, i));
|
Context->getConstantInt(Type::Int32Ty, i),
|
||||||
|
Context);
|
||||||
assert(In && "Couldn't get element of initializer?");
|
assert(In && "Couldn't get element of initializer?");
|
||||||
|
|
||||||
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(), false,
|
GlobalVariable *NGV = new GlobalVariable(STy->getElementType(), false,
|
||||||
@ -543,7 +548,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) {
|
|||||||
|
|
||||||
DOUT << "PERFORMING GLOBAL SRA ON: " << *GV;
|
DOUT << "PERFORMING GLOBAL SRA ON: " << *GV;
|
||||||
|
|
||||||
Constant *NullInt = Constant::getNullValue(Type::Int32Ty);
|
Constant *NullInt = Context->getNullValue(Type::Int32Ty);
|
||||||
|
|
||||||
// Loop over all of the uses of the global, replacing the constantexpr geps,
|
// Loop over all of the uses of the global, replacing the constantexpr geps,
|
||||||
// with smaller constantexpr geps or direct references.
|
// with smaller constantexpr geps or direct references.
|
||||||
@ -568,7 +573,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) {
|
|||||||
Idxs.push_back(NullInt);
|
Idxs.push_back(NullInt);
|
||||||
for (unsigned i = 3, e = CE->getNumOperands(); i != e; ++i)
|
for (unsigned i = 3, e = CE->getNumOperands(); i != e; ++i)
|
||||||
Idxs.push_back(CE->getOperand(i));
|
Idxs.push_back(CE->getOperand(i));
|
||||||
NewPtr = ConstantExpr::getGetElementPtr(cast<Constant>(NewPtr),
|
NewPtr = Context->getConstantExprGetElementPtr(cast<Constant>(NewPtr),
|
||||||
&Idxs[0], Idxs.size());
|
&Idxs[0], Idxs.size());
|
||||||
} else {
|
} else {
|
||||||
GetElementPtrInst *GEPI = cast<GetElementPtrInst>(GEP);
|
GetElementPtrInst *GEPI = cast<GetElementPtrInst>(GEP);
|
||||||
@ -667,7 +672,8 @@ static bool AllUsesOfLoadedValueWillTrapIfNull(GlobalVariable *GV) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
|
static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV,
|
||||||
|
LLVMContext* Context) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ) {
|
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ) {
|
||||||
Instruction *I = cast<Instruction>(*UI++);
|
Instruction *I = cast<Instruction>(*UI++);
|
||||||
@ -699,8 +705,8 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
|
|||||||
}
|
}
|
||||||
} else if (CastInst *CI = dyn_cast<CastInst>(I)) {
|
} else if (CastInst *CI = dyn_cast<CastInst>(I)) {
|
||||||
Changed |= OptimizeAwayTrappingUsesOfValue(CI,
|
Changed |= OptimizeAwayTrappingUsesOfValue(CI,
|
||||||
ConstantExpr::getCast(CI->getOpcode(),
|
Context->getConstantExprCast(CI->getOpcode(),
|
||||||
NewV, CI->getType()));
|
NewV, CI->getType()), Context);
|
||||||
if (CI->use_empty()) {
|
if (CI->use_empty()) {
|
||||||
Changed = true;
|
Changed = true;
|
||||||
CI->eraseFromParent();
|
CI->eraseFromParent();
|
||||||
@ -717,8 +723,8 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
|
|||||||
break;
|
break;
|
||||||
if (Idxs.size() == GEPI->getNumOperands()-1)
|
if (Idxs.size() == GEPI->getNumOperands()-1)
|
||||||
Changed |= OptimizeAwayTrappingUsesOfValue(GEPI,
|
Changed |= OptimizeAwayTrappingUsesOfValue(GEPI,
|
||||||
ConstantExpr::getGetElementPtr(NewV, &Idxs[0],
|
Context->getConstantExprGetElementPtr(NewV, &Idxs[0],
|
||||||
Idxs.size()));
|
Idxs.size()), Context);
|
||||||
if (GEPI->use_empty()) {
|
if (GEPI->use_empty()) {
|
||||||
Changed = true;
|
Changed = true;
|
||||||
GEPI->eraseFromParent();
|
GEPI->eraseFromParent();
|
||||||
@ -734,7 +740,8 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
|
|||||||
/// value stored into it. If there are uses of the loaded value that would trap
|
/// value stored into it. If there are uses of the loaded value that would trap
|
||||||
/// if the loaded value is dynamically null, then we know that they cannot be
|
/// if the loaded value is dynamically null, then we know that they cannot be
|
||||||
/// reachable with a null optimize away the load.
|
/// reachable with a null optimize away the load.
|
||||||
static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV) {
|
static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV,
|
||||||
|
LLVMContext* Context) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
// Keep track of whether we are able to remove all the uses of the global
|
// Keep track of whether we are able to remove all the uses of the global
|
||||||
@ -745,7 +752,7 @@ static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV) {
|
|||||||
for (Value::use_iterator GUI = GV->use_begin(), E = GV->use_end(); GUI != E;){
|
for (Value::use_iterator GUI = GV->use_begin(), E = GV->use_end(); GUI != E;){
|
||||||
User *GlobalUser = *GUI++;
|
User *GlobalUser = *GUI++;
|
||||||
if (LoadInst *LI = dyn_cast<LoadInst>(GlobalUser)) {
|
if (LoadInst *LI = dyn_cast<LoadInst>(GlobalUser)) {
|
||||||
Changed |= OptimizeAwayTrappingUsesOfValue(LI, LV);
|
Changed |= OptimizeAwayTrappingUsesOfValue(LI, LV, Context);
|
||||||
// If we were able to delete all uses of the loads
|
// If we were able to delete all uses of the loads
|
||||||
if (LI->use_empty()) {
|
if (LI->use_empty()) {
|
||||||
LI->eraseFromParent();
|
LI->eraseFromParent();
|
||||||
@ -808,20 +815,21 @@ static void ConstantPropUsersOf(Value *V) {
|
|||||||
/// malloc, there is no reason to actually DO the malloc. Instead, turn the
|
/// malloc, there is no reason to actually DO the malloc. Instead, turn the
|
||||||
/// malloc into a global, and any loads of GV as uses of the new global.
|
/// malloc into a global, and any loads of GV as uses of the new global.
|
||||||
static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
||||||
MallocInst *MI) {
|
MallocInst *MI,
|
||||||
|
LLVMContext* Context) {
|
||||||
DOUT << "PROMOTING MALLOC GLOBAL: " << *GV << " MALLOC = " << *MI;
|
DOUT << "PROMOTING MALLOC GLOBAL: " << *GV << " MALLOC = " << *MI;
|
||||||
ConstantInt *NElements = cast<ConstantInt>(MI->getArraySize());
|
ConstantInt *NElements = cast<ConstantInt>(MI->getArraySize());
|
||||||
|
|
||||||
if (NElements->getZExtValue() != 1) {
|
if (NElements->getZExtValue() != 1) {
|
||||||
// If we have an array allocation, transform it to a single element
|
// If we have an array allocation, transform it to a single element
|
||||||
// allocation to make the code below simpler.
|
// allocation to make the code below simpler.
|
||||||
Type *NewTy = ArrayType::get(MI->getAllocatedType(),
|
Type *NewTy = Context->getArrayType(MI->getAllocatedType(),
|
||||||
NElements->getZExtValue());
|
NElements->getZExtValue());
|
||||||
MallocInst *NewMI =
|
MallocInst *NewMI =
|
||||||
new MallocInst(NewTy, Constant::getNullValue(Type::Int32Ty),
|
new MallocInst(NewTy, Context->getNullValue(Type::Int32Ty),
|
||||||
MI->getAlignment(), MI->getName(), MI);
|
MI->getAlignment(), MI->getName(), MI);
|
||||||
Value* Indices[2];
|
Value* Indices[2];
|
||||||
Indices[0] = Indices[1] = Constant::getNullValue(Type::Int32Ty);
|
Indices[0] = Indices[1] = Context->getNullValue(Type::Int32Ty);
|
||||||
Value *NewGEP = GetElementPtrInst::Create(NewMI, Indices, Indices + 2,
|
Value *NewGEP = GetElementPtrInst::Create(NewMI, Indices, Indices + 2,
|
||||||
NewMI->getName()+".el0", MI);
|
NewMI->getName()+".el0", MI);
|
||||||
MI->replaceAllUsesWith(NewGEP);
|
MI->replaceAllUsesWith(NewGEP);
|
||||||
@ -831,7 +839,7 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
|||||||
|
|
||||||
// Create the new global variable. The contents of the malloc'd memory is
|
// Create the new global variable. The contents of the malloc'd memory is
|
||||||
// undefined, so initialize with an undef value.
|
// undefined, so initialize with an undef value.
|
||||||
Constant *Init = UndefValue::get(MI->getAllocatedType());
|
Constant *Init = Context->getUndef(MI->getAllocatedType());
|
||||||
GlobalVariable *NewGV = new GlobalVariable(MI->getAllocatedType(), false,
|
GlobalVariable *NewGV = new GlobalVariable(MI->getAllocatedType(), false,
|
||||||
GlobalValue::InternalLinkage, Init,
|
GlobalValue::InternalLinkage, Init,
|
||||||
GV->getName()+".body",
|
GV->getName()+".body",
|
||||||
@ -847,14 +855,14 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
|||||||
|
|
||||||
Constant *RepValue = NewGV;
|
Constant *RepValue = NewGV;
|
||||||
if (NewGV->getType() != GV->getType()->getElementType())
|
if (NewGV->getType() != GV->getType()->getElementType())
|
||||||
RepValue = ConstantExpr::getBitCast(RepValue,
|
RepValue = Context->getConstantExprBitCast(RepValue,
|
||||||
GV->getType()->getElementType());
|
GV->getType()->getElementType());
|
||||||
|
|
||||||
// If there is a comparison against null, we will insert a global bool to
|
// If there is a comparison against null, we will insert a global bool to
|
||||||
// keep track of whether the global was initialized yet or not.
|
// keep track of whether the global was initialized yet or not.
|
||||||
GlobalVariable *InitBool =
|
GlobalVariable *InitBool =
|
||||||
new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage,
|
new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage,
|
||||||
ConstantInt::getFalse(), GV->getName()+".init",
|
Context->getConstantIntFalse(), GV->getName()+".init",
|
||||||
(Module *)NULL, GV->isThreadLocal());
|
(Module *)NULL, GV->isThreadLocal());
|
||||||
bool InitBoolUsed = false;
|
bool InitBoolUsed = false;
|
||||||
|
|
||||||
@ -875,7 +883,7 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
|||||||
default: assert(0 && "Unknown ICmp Predicate!");
|
default: assert(0 && "Unknown ICmp Predicate!");
|
||||||
case ICmpInst::ICMP_ULT:
|
case ICmpInst::ICMP_ULT:
|
||||||
case ICmpInst::ICMP_SLT:
|
case ICmpInst::ICMP_SLT:
|
||||||
LV = ConstantInt::getFalse(); // X < null -> always false
|
LV = Context->getConstantIntFalse(); // X < null -> always false
|
||||||
break;
|
break;
|
||||||
case ICmpInst::ICMP_ULE:
|
case ICmpInst::ICMP_ULE:
|
||||||
case ICmpInst::ICMP_SLE:
|
case ICmpInst::ICMP_SLE:
|
||||||
@ -897,7 +905,7 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
|
|||||||
} else {
|
} else {
|
||||||
StoreInst *SI = cast<StoreInst>(GV->use_back());
|
StoreInst *SI = cast<StoreInst>(GV->use_back());
|
||||||
// The global is initialized when the store to it occurs.
|
// The global is initialized when the store to it occurs.
|
||||||
new StoreInst(ConstantInt::getTrue(), InitBool, SI);
|
new StoreInst(Context->getConstantIntTrue(), InitBool, SI);
|
||||||
SI->eraseFromParent();
|
SI->eraseFromParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1121,7 +1129,8 @@ static bool AllGlobalLoadUsesSimpleEnoughForHeapSRA(GlobalVariable *GV,
|
|||||||
|
|
||||||
static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
|
static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
|
||||||
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
|
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
|
||||||
std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite) {
|
std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite,
|
||||||
|
LLVMContext* Context) {
|
||||||
std::vector<Value*> &FieldVals = InsertedScalarizedValues[V];
|
std::vector<Value*> &FieldVals = InsertedScalarizedValues[V];
|
||||||
|
|
||||||
if (FieldNo >= FieldVals.size())
|
if (FieldNo >= FieldVals.size())
|
||||||
@ -1139,7 +1148,7 @@ static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
|
|||||||
// a new Load of the scalarized global.
|
// a new Load of the scalarized global.
|
||||||
Result = new LoadInst(GetHeapSROAValue(LI->getOperand(0), FieldNo,
|
Result = new LoadInst(GetHeapSROAValue(LI->getOperand(0), FieldNo,
|
||||||
InsertedScalarizedValues,
|
InsertedScalarizedValues,
|
||||||
PHIsToRewrite),
|
PHIsToRewrite, Context),
|
||||||
LI->getName()+".f" + utostr(FieldNo), LI);
|
LI->getName()+".f" + utostr(FieldNo), LI);
|
||||||
} else if (PHINode *PN = dyn_cast<PHINode>(V)) {
|
} else if (PHINode *PN = dyn_cast<PHINode>(V)) {
|
||||||
// PN's type is pointer to struct. Make a new PHI of pointer to struct
|
// PN's type is pointer to struct. Make a new PHI of pointer to struct
|
||||||
@ -1147,7 +1156,8 @@ static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
|
|||||||
const StructType *ST =
|
const StructType *ST =
|
||||||
cast<StructType>(cast<PointerType>(PN->getType())->getElementType());
|
cast<StructType>(cast<PointerType>(PN->getType())->getElementType());
|
||||||
|
|
||||||
Result =PHINode::Create(PointerType::getUnqual(ST->getElementType(FieldNo)),
|
Result =
|
||||||
|
PHINode::Create(Context->getPointerTypeUnqual(ST->getElementType(FieldNo)),
|
||||||
PN->getName()+".f"+utostr(FieldNo), PN);
|
PN->getName()+".f"+utostr(FieldNo), PN);
|
||||||
PHIsToRewrite.push_back(std::make_pair(PN, FieldNo));
|
PHIsToRewrite.push_back(std::make_pair(PN, FieldNo));
|
||||||
} else {
|
} else {
|
||||||
@ -1162,17 +1172,19 @@ static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
|
|||||||
/// the load, rewrite the derived value to use the HeapSRoA'd load.
|
/// the load, rewrite the derived value to use the HeapSRoA'd load.
|
||||||
static void RewriteHeapSROALoadUser(Instruction *LoadUser,
|
static void RewriteHeapSROALoadUser(Instruction *LoadUser,
|
||||||
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
|
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
|
||||||
std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite) {
|
std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite,
|
||||||
|
LLVMContext* Context) {
|
||||||
// If this is a comparison against null, handle it.
|
// If this is a comparison against null, handle it.
|
||||||
if (ICmpInst *SCI = dyn_cast<ICmpInst>(LoadUser)) {
|
if (ICmpInst *SCI = dyn_cast<ICmpInst>(LoadUser)) {
|
||||||
assert(isa<ConstantPointerNull>(SCI->getOperand(1)));
|
assert(isa<ConstantPointerNull>(SCI->getOperand(1)));
|
||||||
// If we have a setcc of the loaded pointer, we can use a setcc of any
|
// If we have a setcc of the loaded pointer, we can use a setcc of any
|
||||||
// field.
|
// field.
|
||||||
Value *NPtr = GetHeapSROAValue(SCI->getOperand(0), 0,
|
Value *NPtr = GetHeapSROAValue(SCI->getOperand(0), 0,
|
||||||
InsertedScalarizedValues, PHIsToRewrite);
|
InsertedScalarizedValues, PHIsToRewrite,
|
||||||
|
Context);
|
||||||
|
|
||||||
Value *New = new ICmpInst(SCI->getPredicate(), NPtr,
|
Value *New = new ICmpInst(SCI->getPredicate(), NPtr,
|
||||||
Constant::getNullValue(NPtr->getType()),
|
Context->getNullValue(NPtr->getType()),
|
||||||
SCI->getName(), SCI);
|
SCI->getName(), SCI);
|
||||||
SCI->replaceAllUsesWith(New);
|
SCI->replaceAllUsesWith(New);
|
||||||
SCI->eraseFromParent();
|
SCI->eraseFromParent();
|
||||||
@ -1187,7 +1199,8 @@ static void RewriteHeapSROALoadUser(Instruction *LoadUser,
|
|||||||
// Load the pointer for this field.
|
// Load the pointer for this field.
|
||||||
unsigned FieldNo = cast<ConstantInt>(GEPI->getOperand(2))->getZExtValue();
|
unsigned FieldNo = cast<ConstantInt>(GEPI->getOperand(2))->getZExtValue();
|
||||||
Value *NewPtr = GetHeapSROAValue(GEPI->getOperand(0), FieldNo,
|
Value *NewPtr = GetHeapSROAValue(GEPI->getOperand(0), FieldNo,
|
||||||
InsertedScalarizedValues, PHIsToRewrite);
|
InsertedScalarizedValues, PHIsToRewrite,
|
||||||
|
Context);
|
||||||
|
|
||||||
// Create the new GEP idx vector.
|
// Create the new GEP idx vector.
|
||||||
SmallVector<Value*, 8> GEPIdx;
|
SmallVector<Value*, 8> GEPIdx;
|
||||||
@ -1219,7 +1232,8 @@ static void RewriteHeapSROALoadUser(Instruction *LoadUser,
|
|||||||
// users.
|
// users.
|
||||||
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end(); UI != E; ) {
|
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end(); UI != E; ) {
|
||||||
Instruction *User = cast<Instruction>(*UI++);
|
Instruction *User = cast<Instruction>(*UI++);
|
||||||
RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite);
|
RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite,
|
||||||
|
Context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1229,11 +1243,13 @@ static void RewriteHeapSROALoadUser(Instruction *LoadUser,
|
|||||||
/// AllGlobalLoadUsesSimpleEnoughForHeapSRA.
|
/// AllGlobalLoadUsesSimpleEnoughForHeapSRA.
|
||||||
static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Load,
|
static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Load,
|
||||||
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
|
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
|
||||||
std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite) {
|
std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite,
|
||||||
|
LLVMContext* Context) {
|
||||||
for (Value::use_iterator UI = Load->use_begin(), E = Load->use_end();
|
for (Value::use_iterator UI = Load->use_begin(), E = Load->use_end();
|
||||||
UI != E; ) {
|
UI != E; ) {
|
||||||
Instruction *User = cast<Instruction>(*UI++);
|
Instruction *User = cast<Instruction>(*UI++);
|
||||||
RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite);
|
RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite,
|
||||||
|
Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Load->use_empty()) {
|
if (Load->use_empty()) {
|
||||||
@ -1244,7 +1260,8 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Load,
|
|||||||
|
|
||||||
/// PerformHeapAllocSRoA - MI is an allocation of an array of structures. Break
|
/// PerformHeapAllocSRoA - MI is an allocation of an array of structures. Break
|
||||||
/// it up into multiple allocations of arrays of the fields.
|
/// it up into multiple allocations of arrays of the fields.
|
||||||
static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI,
|
||||||
|
LLVMContext* Context){
|
||||||
DOUT << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *MI;
|
DOUT << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *MI;
|
||||||
const StructType *STy = cast<StructType>(MI->getAllocatedType());
|
const StructType *STy = cast<StructType>(MI->getAllocatedType());
|
||||||
|
|
||||||
@ -1261,11 +1278,11 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
|
|
||||||
for (unsigned FieldNo = 0, e = STy->getNumElements(); FieldNo != e;++FieldNo){
|
for (unsigned FieldNo = 0, e = STy->getNumElements(); FieldNo != e;++FieldNo){
|
||||||
const Type *FieldTy = STy->getElementType(FieldNo);
|
const Type *FieldTy = STy->getElementType(FieldNo);
|
||||||
const Type *PFieldTy = PointerType::getUnqual(FieldTy);
|
const Type *PFieldTy = Context->getPointerTypeUnqual(FieldTy);
|
||||||
|
|
||||||
GlobalVariable *NGV =
|
GlobalVariable *NGV =
|
||||||
new GlobalVariable(PFieldTy, false, GlobalValue::InternalLinkage,
|
new GlobalVariable(PFieldTy, false, GlobalValue::InternalLinkage,
|
||||||
Constant::getNullValue(PFieldTy),
|
Context->getNullValue(PFieldTy),
|
||||||
GV->getName() + ".f" + utostr(FieldNo), GV,
|
GV->getName() + ".f" + utostr(FieldNo), GV,
|
||||||
GV->isThreadLocal());
|
GV->isThreadLocal());
|
||||||
FieldGlobals.push_back(NGV);
|
FieldGlobals.push_back(NGV);
|
||||||
@ -1291,7 +1308,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
Value *RunningOr = 0;
|
Value *RunningOr = 0;
|
||||||
for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) {
|
||||||
Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, FieldMallocs[i],
|
Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, FieldMallocs[i],
|
||||||
Constant::getNullValue(FieldMallocs[i]->getType()),
|
Context->getNullValue(FieldMallocs[i]->getType()),
|
||||||
"isnull", MI);
|
"isnull", MI);
|
||||||
if (!RunningOr)
|
if (!RunningOr)
|
||||||
RunningOr = Cond; // First seteq
|
RunningOr = Cond; // First seteq
|
||||||
@ -1318,7 +1335,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
|
for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
|
||||||
Value *GVVal = new LoadInst(FieldGlobals[i], "tmp", NullPtrBlock);
|
Value *GVVal = new LoadInst(FieldGlobals[i], "tmp", NullPtrBlock);
|
||||||
Value *Cmp = new ICmpInst(ICmpInst::ICMP_NE, GVVal,
|
Value *Cmp = new ICmpInst(ICmpInst::ICMP_NE, GVVal,
|
||||||
Constant::getNullValue(GVVal->getType()),
|
Context->getNullValue(GVVal->getType()),
|
||||||
"tmp", NullPtrBlock);
|
"tmp", NullPtrBlock);
|
||||||
BasicBlock *FreeBlock = BasicBlock::Create("free_it", OrigBB->getParent());
|
BasicBlock *FreeBlock = BasicBlock::Create("free_it", OrigBB->getParent());
|
||||||
BasicBlock *NextBlock = BasicBlock::Create("next", OrigBB->getParent());
|
BasicBlock *NextBlock = BasicBlock::Create("next", OrigBB->getParent());
|
||||||
@ -1326,7 +1343,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
|
|
||||||
// Fill in FreeBlock.
|
// Fill in FreeBlock.
|
||||||
new FreeInst(GVVal, FreeBlock);
|
new FreeInst(GVVal, FreeBlock);
|
||||||
new StoreInst(Constant::getNullValue(GVVal->getType()), FieldGlobals[i],
|
new StoreInst(Context->getNullValue(GVVal->getType()), FieldGlobals[i],
|
||||||
FreeBlock);
|
FreeBlock);
|
||||||
BranchInst::Create(NextBlock, FreeBlock);
|
BranchInst::Create(NextBlock, FreeBlock);
|
||||||
|
|
||||||
@ -1353,7 +1370,8 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
Instruction *User = cast<Instruction>(*UI++);
|
Instruction *User = cast<Instruction>(*UI++);
|
||||||
|
|
||||||
if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
|
if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
|
||||||
RewriteUsesOfLoadForHeapSRoA(LI, InsertedScalarizedValues, PHIsToRewrite);
|
RewriteUsesOfLoadForHeapSRoA(LI, InsertedScalarizedValues, PHIsToRewrite,
|
||||||
|
Context);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1365,7 +1383,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
// Insert a store of null into each global.
|
// Insert a store of null into each global.
|
||||||
for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
|
for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
|
||||||
const PointerType *PT = cast<PointerType>(FieldGlobals[i]->getType());
|
const PointerType *PT = cast<PointerType>(FieldGlobals[i]->getType());
|
||||||
Constant *Null = Constant::getNullValue(PT->getElementType());
|
Constant *Null = Context->getNullValue(PT->getElementType());
|
||||||
new StoreInst(Null, FieldGlobals[i], SI);
|
new StoreInst(Null, FieldGlobals[i], SI);
|
||||||
}
|
}
|
||||||
// Erase the original store.
|
// Erase the original store.
|
||||||
@ -1384,7 +1402,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
||||||
Value *InVal = PN->getIncomingValue(i);
|
Value *InVal = PN->getIncomingValue(i);
|
||||||
InVal = GetHeapSROAValue(InVal, FieldNo, InsertedScalarizedValues,
|
InVal = GetHeapSROAValue(InVal, FieldNo, InsertedScalarizedValues,
|
||||||
PHIsToRewrite);
|
PHIsToRewrite, Context);
|
||||||
FieldPN->addIncoming(InVal, PN->getIncomingBlock(i));
|
FieldPN->addIncoming(InVal, PN->getIncomingBlock(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1422,7 +1440,8 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
|
|||||||
static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
||||||
MallocInst *MI,
|
MallocInst *MI,
|
||||||
Module::global_iterator &GVI,
|
Module::global_iterator &GVI,
|
||||||
TargetData &TD) {
|
TargetData &TD,
|
||||||
|
LLVMContext* Context) {
|
||||||
// If this is a malloc of an abstract type, don't touch it.
|
// If this is a malloc of an abstract type, don't touch it.
|
||||||
if (!MI->getAllocatedType()->isSized())
|
if (!MI->getAllocatedType()->isSized())
|
||||||
return false;
|
return false;
|
||||||
@ -1458,7 +1477,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
// something.
|
// something.
|
||||||
if (NElements->getZExtValue()*
|
if (NElements->getZExtValue()*
|
||||||
TD.getTypeAllocSize(MI->getAllocatedType()) < 2048) {
|
TD.getTypeAllocSize(MI->getAllocatedType()) < 2048) {
|
||||||
GVI = OptimizeGlobalAddressOfMalloc(GV, MI);
|
GVI = OptimizeGlobalAddressOfMalloc(GV, MI, Context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1485,7 +1504,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
if (const ArrayType *AT = dyn_cast<ArrayType>(MI->getAllocatedType())) {
|
if (const ArrayType *AT = dyn_cast<ArrayType>(MI->getAllocatedType())) {
|
||||||
MallocInst *NewMI =
|
MallocInst *NewMI =
|
||||||
new MallocInst(AllocSTy,
|
new MallocInst(AllocSTy,
|
||||||
ConstantInt::get(Type::Int32Ty, AT->getNumElements()),
|
Context->getConstantInt(Type::Int32Ty, AT->getNumElements()),
|
||||||
"", MI);
|
"", MI);
|
||||||
NewMI->takeName(MI);
|
NewMI->takeName(MI);
|
||||||
Value *Cast = new BitCastInst(NewMI, MI->getType(), "tmp", MI);
|
Value *Cast = new BitCastInst(NewMI, MI->getType(), "tmp", MI);
|
||||||
@ -1494,7 +1513,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
MI = NewMI;
|
MI = NewMI;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVI = PerformHeapAllocSRoA(GV, MI);
|
GVI = PerformHeapAllocSRoA(GV, MI, Context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1506,7 +1525,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
// that only one value (besides its initializer) is ever stored to the global.
|
// that only one value (besides its initializer) is ever stored to the global.
|
||||||
static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
|
static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
|
||||||
Module::global_iterator &GVI,
|
Module::global_iterator &GVI,
|
||||||
TargetData &TD) {
|
TargetData &TD, LLVMContext* Context) {
|
||||||
// Ignore no-op GEPs and bitcasts.
|
// Ignore no-op GEPs and bitcasts.
|
||||||
StoredOnceVal = StoredOnceVal->stripPointerCasts();
|
StoredOnceVal = StoredOnceVal->stripPointerCasts();
|
||||||
|
|
||||||
@ -1518,13 +1537,14 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
|
|||||||
GV->getInitializer()->isNullValue()) {
|
GV->getInitializer()->isNullValue()) {
|
||||||
if (Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
|
if (Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
|
||||||
if (GV->getInitializer()->getType() != SOVC->getType())
|
if (GV->getInitializer()->getType() != SOVC->getType())
|
||||||
SOVC = ConstantExpr::getBitCast(SOVC, GV->getInitializer()->getType());
|
SOVC =
|
||||||
|
Context->getConstantExprBitCast(SOVC, GV->getInitializer()->getType());
|
||||||
|
|
||||||
// Optimize away any trapping uses of the loaded value.
|
// Optimize away any trapping uses of the loaded value.
|
||||||
if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC))
|
if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC, Context))
|
||||||
return true;
|
return true;
|
||||||
} else if (MallocInst *MI = dyn_cast<MallocInst>(StoredOnceVal)) {
|
} else if (MallocInst *MI = dyn_cast<MallocInst>(StoredOnceVal)) {
|
||||||
if (TryToOptimizeStoreOfMallocToGlobal(GV, MI, GVI, TD))
|
if (TryToOptimizeStoreOfMallocToGlobal(GV, MI, GVI, TD, Context))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1536,7 +1556,8 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
|
|||||||
/// two values ever stored into GV are its initializer and OtherVal. See if we
|
/// two values ever stored into GV are its initializer and OtherVal. See if we
|
||||||
/// can shrink the global into a boolean and select between the two values
|
/// can shrink the global into a boolean and select between the two values
|
||||||
/// whenever it is used. This exposes the values to other scalar optimizations.
|
/// whenever it is used. This exposes the values to other scalar optimizations.
|
||||||
static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
|
static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal,
|
||||||
|
LLVMContext* Context) {
|
||||||
const Type *GVElType = GV->getType()->getElementType();
|
const Type *GVElType = GV->getType()->getElementType();
|
||||||
|
|
||||||
// If GVElType is already i1, it is already shrunk. If the type of the GV is
|
// If GVElType is already i1, it is already shrunk. If the type of the GV is
|
||||||
@ -1558,7 +1579,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
|
|||||||
|
|
||||||
// Create the new global, initializing it to false.
|
// Create the new global, initializing it to false.
|
||||||
GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false,
|
GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false,
|
||||||
GlobalValue::InternalLinkage, ConstantInt::getFalse(),
|
GlobalValue::InternalLinkage, Context->getConstantIntFalse(),
|
||||||
GV->getName()+".b",
|
GV->getName()+".b",
|
||||||
(Module *)NULL,
|
(Module *)NULL,
|
||||||
GV->isThreadLocal());
|
GV->isThreadLocal());
|
||||||
@ -1581,7 +1602,7 @@ static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
|
|||||||
// Only do this if we weren't storing a loaded value.
|
// Only do this if we weren't storing a loaded value.
|
||||||
Value *StoreVal;
|
Value *StoreVal;
|
||||||
if (StoringOther || SI->getOperand(0) == InitVal)
|
if (StoringOther || SI->getOperand(0) == InitVal)
|
||||||
StoreVal = ConstantInt::get(Type::Int1Ty, StoringOther);
|
StoreVal = Context->getConstantInt(Type::Int1Ty, StoringOther);
|
||||||
else {
|
else {
|
||||||
// Otherwise, we are storing a previously loaded copy. To do this,
|
// Otherwise, we are storing a previously loaded copy. To do this,
|
||||||
// change the copy from copying the original value to just copying the
|
// change the copy from copying the original value to just copying the
|
||||||
@ -1725,7 +1746,8 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
|
|||||||
return true;
|
return true;
|
||||||
} else if (!GV->getInitializer()->getType()->isSingleValueType()) {
|
} else if (!GV->getInitializer()->getType()->isSingleValueType()) {
|
||||||
if (GlobalVariable *FirstNewGV = SRAGlobal(GV,
|
if (GlobalVariable *FirstNewGV = SRAGlobal(GV,
|
||||||
getAnalysis<TargetData>())) {
|
getAnalysis<TargetData>(),
|
||||||
|
Context)) {
|
||||||
GVI = FirstNewGV; // Don't skip the newly produced globals!
|
GVI = FirstNewGV; // Don't skip the newly produced globals!
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1757,13 +1779,13 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
|
|||||||
// Try to optimize globals based on the knowledge that only one value
|
// Try to optimize globals based on the knowledge that only one value
|
||||||
// (besides its initializer) is ever stored to the global.
|
// (besides its initializer) is ever stored to the global.
|
||||||
if (OptimizeOnceStoredGlobal(GV, GS.StoredOnceValue, GVI,
|
if (OptimizeOnceStoredGlobal(GV, GS.StoredOnceValue, GVI,
|
||||||
getAnalysis<TargetData>()))
|
getAnalysis<TargetData>(), Context))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise, if the global was not a boolean, we can shrink it to be a
|
// Otherwise, if the global was not a boolean, we can shrink it to be a
|
||||||
// boolean.
|
// boolean.
|
||||||
if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue))
|
if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue))
|
||||||
if (TryToShrinkGlobalToBoolean(GV, SOVConstant)) {
|
if (TryToShrinkGlobalToBoolean(GV, SOVConstant, Context)) {
|
||||||
++NumShrunkToBool;
|
++NumShrunkToBool;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1916,10 +1938,11 @@ static std::vector<Function*> ParseGlobalCtors(GlobalVariable *GV) {
|
|||||||
/// InstallGlobalCtors - Given a specified llvm.global_ctors list, install the
|
/// InstallGlobalCtors - Given a specified llvm.global_ctors list, install the
|
||||||
/// specified array, returning the new global to use.
|
/// specified array, returning the new global to use.
|
||||||
static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
|
static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
|
||||||
const std::vector<Function*> &Ctors) {
|
const std::vector<Function*> &Ctors,
|
||||||
|
LLVMContext* Context) {
|
||||||
// If we made a change, reassemble the initializer list.
|
// If we made a change, reassemble the initializer list.
|
||||||
std::vector<Constant*> CSVals;
|
std::vector<Constant*> CSVals;
|
||||||
CSVals.push_back(ConstantInt::get(Type::Int32Ty, 65535));
|
CSVals.push_back(Context->getConstantInt(Type::Int32Ty, 65535));
|
||||||
CSVals.push_back(0);
|
CSVals.push_back(0);
|
||||||
|
|
||||||
// Create the new init list.
|
// Create the new init list.
|
||||||
@ -1928,19 +1951,19 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
|
|||||||
if (Ctors[i]) {
|
if (Ctors[i]) {
|
||||||
CSVals[1] = Ctors[i];
|
CSVals[1] = Ctors[i];
|
||||||
} else {
|
} else {
|
||||||
const Type *FTy = FunctionType::get(Type::VoidTy, false);
|
const Type *FTy = Context->getFunctionType(Type::VoidTy, false);
|
||||||
const PointerType *PFTy = PointerType::getUnqual(FTy);
|
const PointerType *PFTy = Context->getPointerTypeUnqual(FTy);
|
||||||
CSVals[1] = Constant::getNullValue(PFTy);
|
CSVals[1] = Context->getNullValue(PFTy);
|
||||||
CSVals[0] = ConstantInt::get(Type::Int32Ty, 2147483647);
|
CSVals[0] = Context->getConstantInt(Type::Int32Ty, 2147483647);
|
||||||
}
|
}
|
||||||
CAList.push_back(ConstantStruct::get(CSVals));
|
CAList.push_back(Context->getConstantStruct(CSVals));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the array initializer.
|
// Create the array initializer.
|
||||||
const Type *StructTy =
|
const Type *StructTy =
|
||||||
cast<ArrayType>(GCL->getType()->getElementType())->getElementType();
|
cast<ArrayType>(GCL->getType()->getElementType())->getElementType();
|
||||||
Constant *CA = ConstantArray::get(ArrayType::get(StructTy, CAList.size()),
|
Constant *CA = Context->getConstantArray(ArrayType::get(StructTy,
|
||||||
CAList);
|
CAList.size()), CAList);
|
||||||
|
|
||||||
// If we didn't change the number of elements, don't create a new GV.
|
// If we didn't change the number of elements, don't create a new GV.
|
||||||
if (CA->getType() == GCL->getInitializer()->getType()) {
|
if (CA->getType() == GCL->getInitializer()->getType()) {
|
||||||
@ -1960,7 +1983,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
|
|||||||
if (!GCL->use_empty()) {
|
if (!GCL->use_empty()) {
|
||||||
Constant *V = NGV;
|
Constant *V = NGV;
|
||||||
if (V->getType() != GCL->getType())
|
if (V->getType() != GCL->getType())
|
||||||
V = ConstantExpr::getBitCast(V, GCL->getType());
|
V = Context->getConstantExprBitCast(V, GCL->getType());
|
||||||
GCL->replaceAllUsesWith(V);
|
GCL->replaceAllUsesWith(V);
|
||||||
}
|
}
|
||||||
GCL->eraseFromParent();
|
GCL->eraseFromParent();
|
||||||
@ -2007,7 +2030,8 @@ static bool isSimpleEnoughPointerToCommit(Constant *C) {
|
|||||||
/// initializer. This returns 'Init' modified to reflect 'Val' stored into it.
|
/// initializer. This returns 'Init' modified to reflect 'Val' stored into it.
|
||||||
/// At this point, the GEP operands of Addr [0, OpNo) have been stepped into.
|
/// At this point, the GEP operands of Addr [0, OpNo) have been stepped into.
|
||||||
static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
|
static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
|
||||||
ConstantExpr *Addr, unsigned OpNo) {
|
ConstantExpr *Addr, unsigned OpNo,
|
||||||
|
LLVMContext* Context) {
|
||||||
// Base case of the recursion.
|
// Base case of the recursion.
|
||||||
if (OpNo == Addr->getNumOperands()) {
|
if (OpNo == Addr->getNumOperands()) {
|
||||||
assert(Val->getType() == Init->getType() && "Type mismatch!");
|
assert(Val->getType() == Init->getType() && "Type mismatch!");
|
||||||
@ -2023,10 +2047,10 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
|
|||||||
Elts.push_back(cast<Constant>(*i));
|
Elts.push_back(cast<Constant>(*i));
|
||||||
} else if (isa<ConstantAggregateZero>(Init)) {
|
} else if (isa<ConstantAggregateZero>(Init)) {
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
||||||
Elts.push_back(Constant::getNullValue(STy->getElementType(i)));
|
Elts.push_back(Context->getNullValue(STy->getElementType(i)));
|
||||||
} else if (isa<UndefValue>(Init)) {
|
} else if (isa<UndefValue>(Init)) {
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
|
||||||
Elts.push_back(UndefValue::get(STy->getElementType(i)));
|
Elts.push_back(Context->getUndef(STy->getElementType(i)));
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "This code is out of sync with "
|
assert(0 && "This code is out of sync with "
|
||||||
" ConstantFoldLoadThroughGEPConstantExpr");
|
" ConstantFoldLoadThroughGEPConstantExpr");
|
||||||
@ -2036,10 +2060,10 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
|
|||||||
ConstantInt *CU = cast<ConstantInt>(Addr->getOperand(OpNo));
|
ConstantInt *CU = cast<ConstantInt>(Addr->getOperand(OpNo));
|
||||||
unsigned Idx = CU->getZExtValue();
|
unsigned Idx = CU->getZExtValue();
|
||||||
assert(Idx < STy->getNumElements() && "Struct index out of range!");
|
assert(Idx < STy->getNumElements() && "Struct index out of range!");
|
||||||
Elts[Idx] = EvaluateStoreInto(Elts[Idx], Val, Addr, OpNo+1);
|
Elts[Idx] = EvaluateStoreInto(Elts[Idx], Val, Addr, OpNo+1, Context);
|
||||||
|
|
||||||
// Return the modified struct.
|
// Return the modified struct.
|
||||||
return ConstantStruct::get(&Elts[0], Elts.size(), STy->isPacked());
|
return Context->getConstantStruct(&Elts[0], Elts.size(), STy->isPacked());
|
||||||
} else {
|
} else {
|
||||||
ConstantInt *CI = cast<ConstantInt>(Addr->getOperand(OpNo));
|
ConstantInt *CI = cast<ConstantInt>(Addr->getOperand(OpNo));
|
||||||
const ArrayType *ATy = cast<ArrayType>(Init->getType());
|
const ArrayType *ATy = cast<ArrayType>(Init->getType());
|
||||||
@ -2050,10 +2074,10 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
|
|||||||
for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i)
|
for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i)
|
||||||
Elts.push_back(cast<Constant>(*i));
|
Elts.push_back(cast<Constant>(*i));
|
||||||
} else if (isa<ConstantAggregateZero>(Init)) {
|
} else if (isa<ConstantAggregateZero>(Init)) {
|
||||||
Constant *Elt = Constant::getNullValue(ATy->getElementType());
|
Constant *Elt = Context->getNullValue(ATy->getElementType());
|
||||||
Elts.assign(ATy->getNumElements(), Elt);
|
Elts.assign(ATy->getNumElements(), Elt);
|
||||||
} else if (isa<UndefValue>(Init)) {
|
} else if (isa<UndefValue>(Init)) {
|
||||||
Constant *Elt = UndefValue::get(ATy->getElementType());
|
Constant *Elt = Context->getUndef(ATy->getElementType());
|
||||||
Elts.assign(ATy->getNumElements(), Elt);
|
Elts.assign(ATy->getNumElements(), Elt);
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "This code is out of sync with "
|
assert(0 && "This code is out of sync with "
|
||||||
@ -2062,14 +2086,15 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
|
|||||||
|
|
||||||
assert(CI->getZExtValue() < ATy->getNumElements());
|
assert(CI->getZExtValue() < ATy->getNumElements());
|
||||||
Elts[CI->getZExtValue()] =
|
Elts[CI->getZExtValue()] =
|
||||||
EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1);
|
EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1, Context);
|
||||||
return ConstantArray::get(ATy, Elts);
|
return Context->getConstantArray(ATy, Elts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CommitValueTo - We have decided that Addr (which satisfies the predicate
|
/// CommitValueTo - We have decided that Addr (which satisfies the predicate
|
||||||
/// isSimpleEnoughPointerToCommit) should get Val as its value. Make it happen.
|
/// isSimpleEnoughPointerToCommit) should get Val as its value. Make it happen.
|
||||||
static void CommitValueTo(Constant *Val, Constant *Addr) {
|
static void CommitValueTo(Constant *Val, Constant *Addr,
|
||||||
|
LLVMContext* Context) {
|
||||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
|
||||||
assert(GV->hasInitializer());
|
assert(GV->hasInitializer());
|
||||||
GV->setInitializer(Val);
|
GV->setInitializer(Val);
|
||||||
@ -2080,7 +2105,7 @@ static void CommitValueTo(Constant *Val, Constant *Addr) {
|
|||||||
GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
|
GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
|
||||||
|
|
||||||
Constant *Init = GV->getInitializer();
|
Constant *Init = GV->getInitializer();
|
||||||
Init = EvaluateStoreInto(Init, Val, CE, 2);
|
Init = EvaluateStoreInto(Init, Val, CE, 2, Context);
|
||||||
GV->setInitializer(Init);
|
GV->setInitializer(Init);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2126,6 +2151,8 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
|||||||
if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end())
|
if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
LLVMContext* Context = F->getContext();
|
||||||
|
|
||||||
CallStack.push_back(F);
|
CallStack.push_back(F);
|
||||||
|
|
||||||
/// Values - As we compute SSA register values, we store their contents here.
|
/// Values - As we compute SSA register values, we store their contents here.
|
||||||
@ -2158,19 +2185,20 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
|||||||
Constant *Val = getVal(Values, SI->getOperand(0));
|
Constant *Val = getVal(Values, SI->getOperand(0));
|
||||||
MutatedMemory[Ptr] = Val;
|
MutatedMemory[Ptr] = Val;
|
||||||
} else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) {
|
} else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) {
|
||||||
InstResult = ConstantExpr::get(BO->getOpcode(),
|
InstResult = Context->getConstantExpr(BO->getOpcode(),
|
||||||
getVal(Values, BO->getOperand(0)),
|
getVal(Values, BO->getOperand(0)),
|
||||||
getVal(Values, BO->getOperand(1)));
|
getVal(Values, BO->getOperand(1)));
|
||||||
} else if (CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
|
} else if (CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
|
||||||
InstResult = ConstantExpr::getCompare(CI->getPredicate(),
|
InstResult = Context->getConstantExprCompare(CI->getPredicate(),
|
||||||
getVal(Values, CI->getOperand(0)),
|
getVal(Values, CI->getOperand(0)),
|
||||||
getVal(Values, CI->getOperand(1)));
|
getVal(Values, CI->getOperand(1)));
|
||||||
} else if (CastInst *CI = dyn_cast<CastInst>(CurInst)) {
|
} else if (CastInst *CI = dyn_cast<CastInst>(CurInst)) {
|
||||||
InstResult = ConstantExpr::getCast(CI->getOpcode(),
|
InstResult = Context->getConstantExprCast(CI->getOpcode(),
|
||||||
getVal(Values, CI->getOperand(0)),
|
getVal(Values, CI->getOperand(0)),
|
||||||
CI->getType());
|
CI->getType());
|
||||||
} else if (SelectInst *SI = dyn_cast<SelectInst>(CurInst)) {
|
} else if (SelectInst *SI = dyn_cast<SelectInst>(CurInst)) {
|
||||||
InstResult = ConstantExpr::getSelect(getVal(Values, SI->getOperand(0)),
|
InstResult =
|
||||||
|
Context->getConstantExprSelect(getVal(Values, SI->getOperand(0)),
|
||||||
getVal(Values, SI->getOperand(1)),
|
getVal(Values, SI->getOperand(1)),
|
||||||
getVal(Values, SI->getOperand(2)));
|
getVal(Values, SI->getOperand(2)));
|
||||||
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurInst)) {
|
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurInst)) {
|
||||||
@ -2179,7 +2207,8 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
|||||||
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end();
|
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end();
|
||||||
i != e; ++i)
|
i != e; ++i)
|
||||||
GEPOps.push_back(getVal(Values, *i));
|
GEPOps.push_back(getVal(Values, *i));
|
||||||
InstResult = ConstantExpr::getGetElementPtr(P, &GEPOps[0], GEPOps.size());
|
InstResult =
|
||||||
|
Context->getConstantExprGetElementPtr(P, &GEPOps[0], GEPOps.size());
|
||||||
} else if (LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {
|
} else if (LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {
|
||||||
if (LI->isVolatile()) return false; // no volatile accesses.
|
if (LI->isVolatile()) return false; // no volatile accesses.
|
||||||
InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)),
|
InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)),
|
||||||
@ -2190,7 +2219,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
|
|||||||
const Type *Ty = AI->getType()->getElementType();
|
const Type *Ty = AI->getType()->getElementType();
|
||||||
AllocaTmps.push_back(new GlobalVariable(Ty, false,
|
AllocaTmps.push_back(new GlobalVariable(Ty, false,
|
||||||
GlobalValue::InternalLinkage,
|
GlobalValue::InternalLinkage,
|
||||||
UndefValue::get(Ty),
|
Context->getUndef(Ty),
|
||||||
AI->getName()));
|
AI->getName()));
|
||||||
InstResult = AllocaTmps.back();
|
InstResult = AllocaTmps.back();
|
||||||
} else if (CallInst *CI = dyn_cast<CallInst>(CurInst)) {
|
} else if (CallInst *CI = dyn_cast<CallInst>(CurInst)) {
|
||||||
@ -2319,7 +2348,7 @@ static bool EvaluateStaticConstructor(Function *F) {
|
|||||||
<< " stores.\n";
|
<< " stores.\n";
|
||||||
for (DenseMap<Constant*, Constant*>::iterator I = MutatedMemory.begin(),
|
for (DenseMap<Constant*, Constant*>::iterator I = MutatedMemory.begin(),
|
||||||
E = MutatedMemory.end(); I != E; ++I)
|
E = MutatedMemory.end(); I != E; ++I)
|
||||||
CommitValueTo(I->second, I->first);
|
CommitValueTo(I->second, I->first, F->getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, we are done interpreting. If we created any 'alloca'
|
// At this point, we are done interpreting. If we created any 'alloca'
|
||||||
@ -2332,7 +2361,7 @@ static bool EvaluateStaticConstructor(Function *F) {
|
|||||||
// silly, e.g. storing the address of the alloca somewhere and using it
|
// silly, e.g. storing the address of the alloca somewhere and using it
|
||||||
// later. Since this is undefined, we'll just make it be null.
|
// later. Since this is undefined, we'll just make it be null.
|
||||||
if (!Tmp->use_empty())
|
if (!Tmp->use_empty())
|
||||||
Tmp->replaceAllUsesWith(Constant::getNullValue(Tmp->getType()));
|
Tmp->replaceAllUsesWith(F->getContext()->getNullValue(Tmp->getType()));
|
||||||
delete Tmp;
|
delete Tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2376,7 +2405,7 @@ bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) {
|
|||||||
|
|
||||||
if (!MadeChange) return false;
|
if (!MadeChange) return false;
|
||||||
|
|
||||||
GCL = InstallGlobalCtors(GCL, Ctors);
|
GCL = InstallGlobalCtors(GCL, Ctors, Context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/Transforms/IPO.h"
|
#include "llvm/Transforms/IPO.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
@ -133,7 +134,7 @@ bool IPCP::PropagateConstantsIntoArguments(Function &F) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Value *V = ArgumentConstants[i].first;
|
Value *V = ArgumentConstants[i].first;
|
||||||
if (V == 0) V = UndefValue::get(AI->getType());
|
if (V == 0) V = Context->getUndef(AI->getType());
|
||||||
AI->replaceAllUsesWith(V);
|
AI->replaceAllUsesWith(V);
|
||||||
++NumArgumentsProped;
|
++NumArgumentsProped;
|
||||||
MadeChange = true;
|
MadeChange = true;
|
||||||
@ -164,9 +165,9 @@ bool IPCP::PropagateConstantReturn(Function &F) {
|
|||||||
const StructType *STy = dyn_cast<StructType>(F.getReturnType());
|
const StructType *STy = dyn_cast<StructType>(F.getReturnType());
|
||||||
if (STy)
|
if (STy)
|
||||||
for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i)
|
for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i)
|
||||||
RetVals.push_back(UndefValue::get(STy->getElementType(i)));
|
RetVals.push_back(Context->getUndef(STy->getElementType(i)));
|
||||||
else
|
else
|
||||||
RetVals.push_back(UndefValue::get(F.getReturnType()));
|
RetVals.push_back(Context->getUndef(F.getReturnType()));
|
||||||
|
|
||||||
unsigned NumNonConstant = 0;
|
unsigned NumNonConstant = 0;
|
||||||
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Intrinsics.h"
|
#include "llvm/Intrinsics.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
@ -200,8 +201,8 @@ bool LowerSetJmp::runOnModule(Module& M) {
|
|||||||
// This function is always successful, unless it isn't.
|
// This function is always successful, unless it isn't.
|
||||||
bool LowerSetJmp::doInitialization(Module& M)
|
bool LowerSetJmp::doInitialization(Module& M)
|
||||||
{
|
{
|
||||||
const Type *SBPTy = PointerType::getUnqual(Type::Int8Ty);
|
const Type *SBPTy = Context->getPointerTypeUnqual(Type::Int8Ty);
|
||||||
const Type *SBPPTy = PointerType::getUnqual(SBPTy);
|
const Type *SBPPTy = Context->getPointerTypeUnqual(SBPTy);
|
||||||
|
|
||||||
// N.B. See llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h for
|
// N.B. See llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h for
|
||||||
// a description of the following library functions.
|
// a description of the following library functions.
|
||||||
@ -257,7 +258,7 @@ bool LowerSetJmp::IsTransformableFunction(const std::string& Name) {
|
|||||||
// throwing the exception for us.
|
// throwing the exception for us.
|
||||||
void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
|
void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
|
||||||
{
|
{
|
||||||
const Type* SBPTy = PointerType::getUnqual(Type::Int8Ty);
|
const Type* SBPTy = Context->getPointerTypeUnqual(Type::Int8Ty);
|
||||||
|
|
||||||
// Create the call to "__llvm_sjljeh_throw_longjmp". This takes the
|
// Create the call to "__llvm_sjljeh_throw_longjmp". This takes the
|
||||||
// same parameters as "longjmp", except that the buffer is cast to a
|
// same parameters as "longjmp", except that the buffer is cast to a
|
||||||
@ -288,7 +289,7 @@ void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
|
|||||||
Removed = &BB->back();
|
Removed = &BB->back();
|
||||||
// If the removed instructions have any users, replace them now.
|
// If the removed instructions have any users, replace them now.
|
||||||
if (!Removed->use_empty())
|
if (!Removed->use_empty())
|
||||||
Removed->replaceAllUsesWith(UndefValue::get(Removed->getType()));
|
Removed->replaceAllUsesWith(Context->getUndef(Removed->getType()));
|
||||||
Removed->eraseFromParent();
|
Removed->eraseFromParent();
|
||||||
} while (Removed != Inst);
|
} while (Removed != Inst);
|
||||||
|
|
||||||
@ -309,7 +310,7 @@ AllocaInst* LowerSetJmp::GetSetJmpMap(Function* Func)
|
|||||||
assert(Inst && "Couldn't find even ONE instruction in entry block!");
|
assert(Inst && "Couldn't find even ONE instruction in entry block!");
|
||||||
|
|
||||||
// Fill in the alloca and call to initialize the SJ map.
|
// Fill in the alloca and call to initialize the SJ map.
|
||||||
const Type *SBPTy = PointerType::getUnqual(Type::Int8Ty);
|
const Type *SBPTy = Context->getPointerTypeUnqual(Type::Int8Ty);
|
||||||
AllocaInst* Map = new AllocaInst(SBPTy, 0, "SJMap", Inst);
|
AllocaInst* Map = new AllocaInst(SBPTy, 0, "SJMap", Inst);
|
||||||
CallInst::Create(InitSJMap, Map, "", Inst);
|
CallInst::Create(InitSJMap, Map, "", Inst);
|
||||||
return SJMap[Func] = Map;
|
return SJMap[Func] = Map;
|
||||||
@ -375,12 +376,12 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
|
|||||||
Function* Func = ABlock->getParent();
|
Function* Func = ABlock->getParent();
|
||||||
|
|
||||||
// Add this setjmp to the setjmp map.
|
// Add this setjmp to the setjmp map.
|
||||||
const Type* SBPTy = PointerType::getUnqual(Type::Int8Ty);
|
const Type* SBPTy = Context->getPointerTypeUnqual(Type::Int8Ty);
|
||||||
CastInst* BufPtr =
|
CastInst* BufPtr =
|
||||||
new BitCastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst);
|
new BitCastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst);
|
||||||
std::vector<Value*> Args =
|
std::vector<Value*> Args =
|
||||||
make_vector<Value*>(GetSetJmpMap(Func), BufPtr,
|
make_vector<Value*>(GetSetJmpMap(Func), BufPtr,
|
||||||
ConstantInt::get(Type::Int32Ty,
|
Context->getConstantInt(Type::Int32Ty,
|
||||||
SetJmpIDMap[Func]++), 0);
|
SetJmpIDMap[Func]++), 0);
|
||||||
CallInst::Create(AddSJToMap, Args.begin(), Args.end(), "", Inst);
|
CallInst::Create(AddSJToMap, Args.begin(), Args.end(), "", Inst);
|
||||||
|
|
||||||
@ -427,12 +428,13 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
|
|||||||
PHINode* PHI = PHINode::Create(Type::Int32Ty, "SetJmpReturn", Inst);
|
PHINode* PHI = PHINode::Create(Type::Int32Ty, "SetJmpReturn", Inst);
|
||||||
|
|
||||||
// Coming from a call to setjmp, the return is 0.
|
// Coming from a call to setjmp, the return is 0.
|
||||||
PHI->addIncoming(ConstantInt::getNullValue(Type::Int32Ty), ABlock);
|
PHI->addIncoming(Context->getNullValue(Type::Int32Ty), ABlock);
|
||||||
|
|
||||||
// Add the case for this setjmp's number...
|
// Add the case for this setjmp's number...
|
||||||
SwitchValuePair SVP = GetSJSwitch(Func, GetRethrowBB(Func));
|
SwitchValuePair SVP = GetSJSwitch(Func, GetRethrowBB(Func));
|
||||||
SVP.first->addCase(ConstantInt::get(Type::Int32Ty, SetJmpIDMap[Func] - 1),
|
SVP.first->addCase(Context->getConstantInt(Type::Int32Ty,
|
||||||
SetJmpContBlock);
|
SetJmpIDMap[Func] - 1),
|
||||||
|
SetJmpContBlock);
|
||||||
|
|
||||||
// Value coming from the handling of the exception.
|
// Value coming from the handling of the exception.
|
||||||
PHI->addIncoming(SVP.second, SVP.second->getParent());
|
PHI->addIncoming(SVP.second, SVP.second->getParent());
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/InlineAsm.h"
|
#include "llvm/InlineAsm.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
@ -517,7 +518,7 @@ static void AliasGToF(Function *F, Function *G) {
|
|||||||
|
|
||||||
GlobalAlias *GA = new GlobalAlias(
|
GlobalAlias *GA = new GlobalAlias(
|
||||||
G->getType(), G->getLinkage(), "",
|
G->getType(), G->getLinkage(), "",
|
||||||
ConstantExpr::getBitCast(F, G->getType()), G->getParent());
|
F->getContext()->getConstantExprBitCast(F, G->getType()), G->getParent());
|
||||||
F->setAlignment(std::max(F->getAlignment(), G->getAlignment()));
|
F->setAlignment(std::max(F->getAlignment(), G->getAlignment()));
|
||||||
GA->takeName(G);
|
GA->takeName(G);
|
||||||
GA->setVisibility(G->getVisibility());
|
GA->setVisibility(G->getVisibility());
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/CallGraphSCCPass.h"
|
#include "llvm/CallGraphSCCPass.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/IntrinsicInst.h"
|
#include "llvm/IntrinsicInst.h"
|
||||||
#include "llvm/Analysis/CallGraph.h"
|
#include "llvm/Analysis/CallGraph.h"
|
||||||
@ -242,7 +243,7 @@ void PruneEH::DeleteBasicBlock(BasicBlock *BB) {
|
|||||||
} else if (InvokeInst *II = dyn_cast<InvokeInst>(I))
|
} else if (InvokeInst *II = dyn_cast<InvokeInst>(I))
|
||||||
CGN->removeCallEdgeFor(II);
|
CGN->removeCallEdgeFor(II);
|
||||||
if (!I->use_empty())
|
if (!I->use_empty())
|
||||||
I->replaceAllUsesWith(UndefValue::get(I->getType()));
|
I->replaceAllUsesWith(Context->getUndef(I->getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the list of successors of this block.
|
// Get the list of successors of this block.
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "llvm/Transforms/IPO.h"
|
#include "llvm/Transforms/IPO.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
@ -77,7 +78,7 @@ void RaiseAllocations::doInitialization(Module &M) {
|
|||||||
|
|
||||||
// Get the expected prototype for malloc
|
// Get the expected prototype for malloc
|
||||||
const FunctionType *Malloc1Type =
|
const FunctionType *Malloc1Type =
|
||||||
FunctionType::get(PointerType::getUnqual(Type::Int8Ty),
|
Context->getFunctionType(Context->getPointerTypeUnqual(Type::Int8Ty),
|
||||||
std::vector<const Type*>(1, Type::Int64Ty), false);
|
std::vector<const Type*>(1, Type::Int64Ty), false);
|
||||||
|
|
||||||
// Chck to see if we got the expected malloc
|
// Chck to see if we got the expected malloc
|
||||||
@ -85,14 +86,15 @@ void RaiseAllocations::doInitialization(Module &M) {
|
|||||||
// Check to see if the prototype is wrong, giving us i8*(i32) * malloc
|
// Check to see if the prototype is wrong, giving us i8*(i32) * malloc
|
||||||
// This handles the common declaration of: 'void *malloc(unsigned);'
|
// This handles the common declaration of: 'void *malloc(unsigned);'
|
||||||
const FunctionType *Malloc2Type =
|
const FunctionType *Malloc2Type =
|
||||||
FunctionType::get(PointerType::getUnqual(Type::Int8Ty),
|
Context->getFunctionType(Context->getPointerTypeUnqual(Type::Int8Ty),
|
||||||
std::vector<const Type*>(1, Type::Int32Ty), false);
|
std::vector<const Type*>(1, Type::Int32Ty), false);
|
||||||
if (TyWeHave != Malloc2Type) {
|
if (TyWeHave != Malloc2Type) {
|
||||||
// Check to see if the prototype is missing, giving us
|
// Check to see if the prototype is missing, giving us
|
||||||
// i8*(...) * malloc
|
// i8*(...) * malloc
|
||||||
// This handles the common declaration of: 'void *malloc();'
|
// This handles the common declaration of: 'void *malloc();'
|
||||||
const FunctionType *Malloc3Type =
|
const FunctionType *Malloc3Type =
|
||||||
FunctionType::get(PointerType::getUnqual(Type::Int8Ty), true);
|
Context->getFunctionType(Context->getPointerTypeUnqual(Type::Int8Ty),
|
||||||
|
true);
|
||||||
if (TyWeHave != Malloc3Type)
|
if (TyWeHave != Malloc3Type)
|
||||||
// Give up
|
// Give up
|
||||||
MallocFunc = 0;
|
MallocFunc = 0;
|
||||||
@ -105,19 +107,22 @@ void RaiseAllocations::doInitialization(Module &M) {
|
|||||||
const FunctionType* TyWeHave = FreeFunc->getFunctionType();
|
const FunctionType* TyWeHave = FreeFunc->getFunctionType();
|
||||||
|
|
||||||
// Get the expected prototype for void free(i8*)
|
// Get the expected prototype for void free(i8*)
|
||||||
const FunctionType *Free1Type = FunctionType::get(Type::VoidTy,
|
const FunctionType *Free1Type = Context->getFunctionType(Type::VoidTy,
|
||||||
std::vector<const Type*>(1, PointerType::getUnqual(Type::Int8Ty)), false);
|
std::vector<const Type*>(1, Context->getPointerTypeUnqual(Type::Int8Ty)),
|
||||||
|
false);
|
||||||
|
|
||||||
if (TyWeHave != Free1Type) {
|
if (TyWeHave != Free1Type) {
|
||||||
// Check to see if the prototype was forgotten, giving us
|
// Check to see if the prototype was forgotten, giving us
|
||||||
// void (...) * free
|
// void (...) * free
|
||||||
// This handles the common forward declaration of: 'void free();'
|
// This handles the common forward declaration of: 'void free();'
|
||||||
const FunctionType* Free2Type = FunctionType::get(Type::VoidTy, true);
|
const FunctionType* Free2Type = Context->getFunctionType(Type::VoidTy,
|
||||||
|
true);
|
||||||
|
|
||||||
if (TyWeHave != Free2Type) {
|
if (TyWeHave != Free2Type) {
|
||||||
// One last try, check to see if we can find free as
|
// One last try, check to see if we can find free as
|
||||||
// int (...)* free. This handles the case where NOTHING was declared.
|
// int (...)* free. This handles the case where NOTHING was declared.
|
||||||
const FunctionType* Free3Type = FunctionType::get(Type::Int32Ty, true);
|
const FunctionType* Free3Type = Context->getFunctionType(Type::Int32Ty,
|
||||||
|
true);
|
||||||
|
|
||||||
if (TyWeHave != Free3Type) {
|
if (TyWeHave != Free3Type) {
|
||||||
// Give up.
|
// Give up.
|
||||||
@ -216,7 +221,7 @@ bool RaiseAllocations::runOnModule(Module &M) {
|
|||||||
Value *Source = *CS.arg_begin();
|
Value *Source = *CS.arg_begin();
|
||||||
if (!isa<PointerType>(Source->getType()))
|
if (!isa<PointerType>(Source->getType()))
|
||||||
Source = new IntToPtrInst(Source,
|
Source = new IntToPtrInst(Source,
|
||||||
PointerType::getUnqual(Type::Int8Ty),
|
Context->getPointerTypeUnqual(Type::Int8Ty),
|
||||||
"FreePtrCast", I);
|
"FreePtrCast", I);
|
||||||
new FreeInst(Source, I);
|
new FreeInst(Source, I);
|
||||||
|
|
||||||
@ -227,7 +232,7 @@ bool RaiseAllocations::runOnModule(Module &M) {
|
|||||||
|
|
||||||
// Delete the old call site
|
// Delete the old call site
|
||||||
if (I->getType() != Type::VoidTy)
|
if (I->getType() != Type::VoidTy)
|
||||||
I->replaceAllUsesWith(UndefValue::get(I->getType()));
|
I->replaceAllUsesWith(Context->getUndef(I->getType()));
|
||||||
I->eraseFromParent();
|
I->eraseFromParent();
|
||||||
Changed = true;
|
Changed = true;
|
||||||
++NumRaised;
|
++NumRaised;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Analysis/DebugInfo.h"
|
#include "llvm/Analysis/DebugInfo.h"
|
||||||
@ -236,7 +237,7 @@ bool StripDebugInfo(Module &M) {
|
|||||||
if (!GV) continue;
|
if (!GV) continue;
|
||||||
if (!GV->use_empty() && llvmUsedValues.count(I) == 0) {
|
if (!GV->use_empty() && llvmUsedValues.count(I) == 0) {
|
||||||
if (strncmp(GV->getNameStart(), "llvm.dbg", 8) == 0) {
|
if (strncmp(GV->getNameStart(), "llvm.dbg", 8) == 0) {
|
||||||
GV->replaceAllUsesWith(UndefValue::get(GV->getType()));
|
GV->replaceAllUsesWith(M.getContext().getUndef(GV->getType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "llvm/Transforms/IPO.h"
|
#include "llvm/Transforms/IPO.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/CallGraphSCCPass.h"
|
#include "llvm/CallGraphSCCPass.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
@ -229,7 +230,7 @@ Function *SRETPromotion::cloneFunctionBody(Function *F,
|
|||||||
AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
|
AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
|
||||||
|
|
||||||
|
|
||||||
FunctionType *NFTy = FunctionType::get(STy, Params, FTy->isVarArg());
|
FunctionType *NFTy = Context->getFunctionType(STy, Params, FTy->isVarArg());
|
||||||
Function *NF = Function::Create(NFTy, F->getLinkage());
|
Function *NF = Function::Create(NFTy, F->getLinkage());
|
||||||
NF->takeName(F);
|
NF->takeName(F);
|
||||||
NF->copyAttributesFrom(F);
|
NF->copyAttributesFrom(F);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user