mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 21:20:37 +00:00
Simplify code (somtimes dramatically), by using the new "auto-insert" feature
of instruction constructors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3656 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3ea5cb0df1
commit
2a7c23ef91
@ -101,21 +101,14 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
|
||||
// If we have a scale, apply it first...
|
||||
if (Expr.Var) {
|
||||
// Expr.Var is not neccesarily unsigned right now, insert a cast now.
|
||||
if (Expr.Var->getType() != Type::UIntTy) {
|
||||
Instruction *CI = new CastInst(Expr.Var, Type::UIntTy);
|
||||
if (Expr.Var->hasName()) CI->setName(Expr.Var->getName()+"-uint");
|
||||
It = ++BB->getInstList().insert(It, CI);
|
||||
Expr.Var = CI;
|
||||
}
|
||||
if (Expr.Var->getType() != Type::UIntTy)
|
||||
Expr.Var = new CastInst(Expr.Var, Type::UIntTy,
|
||||
Expr.Var->getName()+"-uint", It);
|
||||
|
||||
if (Scale != 1) {
|
||||
Instruction *ScI =
|
||||
BinaryOperator::create(Instruction::Mul, Expr.Var,
|
||||
ConstantUInt::get(Type::UIntTy, Scale));
|
||||
if (Expr.Var->hasName()) ScI->setName(Expr.Var->getName()+"-scl");
|
||||
It = ++BB->getInstList().insert(It, ScI);
|
||||
Expr.Var = ScI;
|
||||
}
|
||||
if (Scale != 1)
|
||||
Expr.Var = BinaryOperator::create(Instruction::Mul, Expr.Var,
|
||||
ConstantUInt::get(Type::UIntTy, Scale),
|
||||
Expr.Var->getName()+"-scl", It);
|
||||
|
||||
} else {
|
||||
// If we are not scaling anything, just make the offset be the "var"...
|
||||
@ -126,13 +119,9 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
|
||||
// If we have an offset now, add it in...
|
||||
if (Offset != 0) {
|
||||
assert(Expr.Var && "Var must be nonnull by now!");
|
||||
|
||||
Instruction *AddI =
|
||||
BinaryOperator::create(Instruction::Add, Expr.Var,
|
||||
ConstantUInt::get(Type::UIntTy, Offset));
|
||||
if (Expr.Var->hasName()) AddI->setName(Expr.Var->getName()+"-off");
|
||||
It = ++BB->getInstList().insert(It, AddI);
|
||||
Expr.Var = AddI;
|
||||
Expr.Var = BinaryOperator::create(Instruction::Add, Expr.Var,
|
||||
ConstantUInt::get(Type::UIntTy, Offset),
|
||||
Expr.Var->getName()+"-off", It);
|
||||
}
|
||||
|
||||
Instruction *NewI = new MallocInst(AllocTy, Expr.Var, Name);
|
||||
@ -971,9 +960,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
||||
assert(LoadedTy->isFirstClassType());
|
||||
|
||||
if (Indices.size() != 1) { // Do not generate load X, 0
|
||||
Src = new GetElementPtrInst(Src, Indices, Name+".idx");
|
||||
// Insert the GEP instruction before this load.
|
||||
BIL.insert(I, cast<Instruction>(Src));
|
||||
Src = new GetElementPtrInst(Src, Indices, Name+".idx", I);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1008,10 +996,9 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
||||
assert(Offset == 0 && "Offset changed!");
|
||||
assert(NewTy == Ty && "Did not convert to correct type!");
|
||||
|
||||
// Insert the GEP instruction before this store.
|
||||
SrcPtr = new GetElementPtrInst(SrcPtr, Indices,
|
||||
SrcPtr->getName()+".idx");
|
||||
// Insert the GEP instruction before this load.
|
||||
BIL.insert(I, cast<Instruction>(SrcPtr));
|
||||
SrcPtr->getName()+".idx", I);
|
||||
}
|
||||
Res = new StoreInst(NewVal, SrcPtr);
|
||||
|
||||
@ -1038,10 +1025,9 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
||||
|
||||
assert(Offset == 0 && ValTy);
|
||||
|
||||
// Insert the GEP instruction before this store.
|
||||
SrcPtr = new GetElementPtrInst(SrcPtr, Indices,
|
||||
SrcPtr->getName()+".idx");
|
||||
// Insert the GEP instruction before this load.
|
||||
BIL.insert(I, cast<Instruction>(SrcPtr));
|
||||
SrcPtr->getName()+".idx", I);
|
||||
}
|
||||
|
||||
Res = new StoreInst(Constant::getNullValue(ValTy), SrcPtr);
|
||||
@ -1064,8 +1050,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
||||
if (DataSize != 1) {
|
||||
// Insert a multiply of the old element type is not a unit size...
|
||||
Index = BinaryOperator::create(Instruction::Mul, Index,
|
||||
ConstantUInt::get(Type::UIntTy, DataSize));
|
||||
It = ++BIL.insert(It, cast<Instruction>(Index));
|
||||
ConstantUInt::get(Type::UIntTy, DataSize),
|
||||
"scale", It);
|
||||
}
|
||||
|
||||
// Perform the conversion now...
|
||||
@ -1146,8 +1132,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
||||
// Create a cast to convert it to the right type, we know that this
|
||||
// is a lossless cast...
|
||||
//
|
||||
Params[i] = new CastInst(Params[i], PTs[i], "call.resolve.cast");
|
||||
It = ++BIL.insert(It, cast<Instruction>(Params[i]));
|
||||
Params[i] = new CastInst(Params[i], PTs[i], "call.resolve.cast", It);
|
||||
}
|
||||
Meth = NewVal; // Update call destination to new value
|
||||
|
||||
|
@ -208,7 +208,7 @@ static string getPrintfCodeFor(const Value *V) {
|
||||
}
|
||||
|
||||
|
||||
static void InsertPrintInst(Value *V,BasicBlock *BB, BasicBlock::iterator &BBI,
|
||||
static void InsertPrintInst(Value *V, BasicBlock *BB, Instruction *InsertBefore,
|
||||
string Message,
|
||||
Function *Printf, Function* HashPtrToSeqNum) {
|
||||
// Escape Message by replacing all % characters with %% chars.
|
||||
@ -227,88 +227,59 @@ static void InsertPrintInst(Value *V,BasicBlock *BB, BasicBlock::iterator &BBI,
|
||||
Instruction *GEP =
|
||||
new GetElementPtrInst(fmtVal,
|
||||
vector<Value*>(2,ConstantUInt::get(Type::UIntTy, 0)),
|
||||
"trstr");
|
||||
BBI = ++BB->getInstList().insert(BBI, GEP);
|
||||
"trstr", InsertBefore);
|
||||
|
||||
// Insert a call to the hash function if this is a pointer value
|
||||
if (V && isa<PointerType>(V->getType()) && !DisablePtrHashing) {
|
||||
const Type *SBP = PointerType::get(Type::SByteTy);
|
||||
if (V->getType() != SBP) { // Cast pointer to be sbyte*
|
||||
Instruction *I = new CastInst(V, SBP, "Hash_cast");
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
V = I;
|
||||
}
|
||||
if (V->getType() != SBP) // Cast pointer to be sbyte*
|
||||
V = new CastInst(V, SBP, "Hash_cast", InsertBefore);
|
||||
|
||||
vector<Value*> HashArgs(1, V);
|
||||
V = new CallInst(HashPtrToSeqNum, HashArgs, "ptrSeqNum");
|
||||
BBI = ++BB->getInstList().insert(BBI, cast<Instruction>(V));
|
||||
V = new CallInst(HashPtrToSeqNum, HashArgs, "ptrSeqNum", InsertBefore);
|
||||
}
|
||||
|
||||
// Insert the first print instruction to print the string flag:
|
||||
vector<Value*> PrintArgs;
|
||||
PrintArgs.push_back(GEP);
|
||||
if (V) PrintArgs.push_back(V);
|
||||
Instruction *I = new CallInst(Printf, PrintArgs, "trace");
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
new CallInst(Printf, PrintArgs, "trace", InsertBefore);
|
||||
}
|
||||
|
||||
|
||||
static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
|
||||
BasicBlock::iterator &BBI,
|
||||
Instruction *InsertBefore,
|
||||
const string &Message, Function *Printf,
|
||||
Function* HashPtrToSeqNum) {
|
||||
std::ostringstream OutStr;
|
||||
if (V) WriteAsOperand(OutStr, V);
|
||||
InsertPrintInst(V, BB, BBI, Message+OutStr.str()+" = ",
|
||||
InsertPrintInst(V, BB, InsertBefore, Message+OutStr.str()+" = ",
|
||||
Printf, HashPtrToSeqNum);
|
||||
}
|
||||
|
||||
static void
|
||||
InsertReleaseInst(Value *V, BasicBlock *BB,
|
||||
BasicBlock::iterator &BBI,
|
||||
Instruction *InsertBefore,
|
||||
Function* ReleasePtrFunc) {
|
||||
|
||||
const Type *SBP = PointerType::get(Type::SByteTy);
|
||||
if (V->getType() != SBP) { // Cast pointer to be sbyte*
|
||||
Instruction *I = new CastInst(V, SBP, "RPSN_cast");
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
V = I;
|
||||
}
|
||||
if (V->getType() != SBP) // Cast pointer to be sbyte*
|
||||
V = new CastInst(V, SBP, "RPSN_cast", InsertBefore);
|
||||
|
||||
vector<Value*> releaseArgs(1, V);
|
||||
Instruction *I = new CallInst(ReleasePtrFunc, releaseArgs);
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
new CallInst(ReleasePtrFunc, releaseArgs, "", InsertBefore);
|
||||
}
|
||||
|
||||
static void
|
||||
InsertRecordInst(Value *V, BasicBlock *BB,
|
||||
BasicBlock::iterator &BBI,
|
||||
Instruction *InsertBefore,
|
||||
Function* RecordPtrFunc) {
|
||||
const Type *SBP = PointerType::get(Type::SByteTy);
|
||||
if (V->getType() != SBP) { // Cast pointer to be sbyte*
|
||||
Instruction *I = new CastInst(V, SBP, "RP_cast");
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
V = I;
|
||||
}
|
||||
if (V->getType() != SBP) // Cast pointer to be sbyte*
|
||||
V = new CastInst(V, SBP, "RP_cast", InsertBefore);
|
||||
|
||||
vector<Value*> releaseArgs(1, V);
|
||||
Instruction *I = new CallInst(RecordPtrFunc, releaseArgs);
|
||||
BBI = ++BB->getInstList().insert(BBI, I);
|
||||
}
|
||||
|
||||
static void
|
||||
InsertPushOnEntryFunc(Function *M,
|
||||
Function* PushOnEntryFunc) {
|
||||
// Get an iterator to point to the insertion location
|
||||
BasicBlock &BB = M->getEntryNode();
|
||||
BB.getInstList().insert(BB.begin(), new CallInst(PushOnEntryFunc,
|
||||
vector<Value*>()));
|
||||
}
|
||||
|
||||
static void
|
||||
InsertReleaseRecordedInst(BasicBlock *BB,
|
||||
Function* ReleaseOnReturnFunc) {
|
||||
BasicBlock::iterator BBI = --BB->end();
|
||||
BBI = ++BB->getInstList().insert(BBI, new CallInst(ReleaseOnReturnFunc,
|
||||
vector<Value*>()));
|
||||
new CallInst(RecordPtrFunc, releaseArgs, "", InsertBefore);
|
||||
}
|
||||
|
||||
// Look for alloca and free instructions. These are the ptrs to release.
|
||||
@ -319,16 +290,11 @@ static void
|
||||
ReleasePtrSeqNumbers(BasicBlock *BB,
|
||||
ExternalFuncs& externalFuncs) {
|
||||
|
||||
for (BasicBlock::iterator II=BB->begin(); II != BB->end(); ++II) {
|
||||
for (BasicBlock::iterator II=BB->begin(), IE = BB->end(); II != IE; ++II)
|
||||
if (FreeInst *FI = dyn_cast<FreeInst>(&*II))
|
||||
InsertReleaseInst(FI->getOperand(0), BB,II,externalFuncs.ReleasePtrFunc);
|
||||
InsertReleaseInst(FI->getOperand(0), BB, FI,externalFuncs.ReleasePtrFunc);
|
||||
else if (AllocaInst *AI = dyn_cast<AllocaInst>(&*II))
|
||||
{
|
||||
BasicBlock::iterator nextI = ++II;
|
||||
InsertRecordInst(AI, BB, nextI, externalFuncs.RecordPtrFunc);
|
||||
II = --nextI;
|
||||
}
|
||||
}
|
||||
InsertRecordInst(AI, BB, AI->getNext(), externalFuncs.RecordPtrFunc);
|
||||
}
|
||||
|
||||
|
||||
@ -347,8 +313,7 @@ static void TraceValuesAtBBExit(BasicBlock *BB,
|
||||
// Get an iterator to point to the insertion location, which is
|
||||
// just before the terminator instruction.
|
||||
//
|
||||
BasicBlock::iterator InsertPos = --BB->end();
|
||||
assert(InsertPos->isTerminator());
|
||||
TerminatorInst *InsertPos = BB->getTerminator();
|
||||
|
||||
std::ostringstream OutStr;
|
||||
WriteAsOperand(OutStr, BB, false);
|
||||
@ -359,21 +324,17 @@ static void TraceValuesAtBBExit(BasicBlock *BB,
|
||||
// The print instructions must go before InsertPos, so we use the
|
||||
// instruction *preceding* InsertPos to check when to terminate the loop.
|
||||
//
|
||||
if (InsertPos != BB->begin()) { // there's at least one instr before InsertPos
|
||||
BasicBlock::iterator II = BB->begin(), IEincl = InsertPos;
|
||||
--IEincl;
|
||||
do { // do from II up to IEincl, inclusive
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(&*II)) {
|
||||
assert(valuesStoredInFunction &&
|
||||
"Should not be printing a store instruction at function exit");
|
||||
LoadInst *LI = new LoadInst(SI->getPointerOperand(), "reload." +
|
||||
SI->getPointerOperand()->getName());
|
||||
InsertPos = ++BB->getInstList().insert(InsertPos, LI);
|
||||
valuesStoredInFunction->push_back(LI);
|
||||
}
|
||||
if (ShouldTraceValue(II))
|
||||
InsertVerbosePrintInst(II, BB, InsertPos, " ", Printf,HashPtrToSeqNum);
|
||||
} while (II++ != IEincl);
|
||||
for (BasicBlock::iterator II = BB->begin(); &*II != InsertPos; ++II) {
|
||||
if (StoreInst *SI = dyn_cast<StoreInst>(&*II)) {
|
||||
assert(valuesStoredInFunction &&
|
||||
"Should not be printing a store instruction at function exit");
|
||||
LoadInst *LI = new LoadInst(SI->getPointerOperand(), "reload." +
|
||||
SI->getPointerOperand()->getName(),
|
||||
InsertPos);
|
||||
valuesStoredInFunction->push_back(LI);
|
||||
}
|
||||
if (ShouldTraceValue(II))
|
||||
InsertVerbosePrintInst(II, BB, InsertPos, " ", Printf, HashPtrToSeqNum);
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,17 +342,17 @@ static inline void InsertCodeToShowFunctionEntry(Function &F, Function *Printf,
|
||||
Function* HashPtrToSeqNum){
|
||||
// Get an iterator to point to the insertion location
|
||||
BasicBlock &BB = F.getEntryNode();
|
||||
BasicBlock::iterator BBI = BB.begin();
|
||||
Instruction *InsertPos = BB.begin();
|
||||
|
||||
std::ostringstream OutStr;
|
||||
WriteAsOperand(OutStr, &F, true);
|
||||
InsertPrintInst(0, &BB, BBI, "ENTERING FUNCTION: " + OutStr.str(),
|
||||
InsertPrintInst(0, &BB, InsertPos, "ENTERING FUNCTION: " + OutStr.str(),
|
||||
Printf, HashPtrToSeqNum);
|
||||
|
||||
// Now print all the incoming arguments
|
||||
unsigned ArgNo = 0;
|
||||
for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++ArgNo){
|
||||
InsertVerbosePrintInst(I, &BB, BBI,
|
||||
InsertVerbosePrintInst(I, &BB, InsertPos,
|
||||
" Arg #" + utostr(ArgNo) + ": ", Printf,
|
||||
HashPtrToSeqNum);
|
||||
}
|
||||
@ -402,17 +363,16 @@ static inline void InsertCodeToShowFunctionExit(BasicBlock *BB,
|
||||
Function *Printf,
|
||||
Function* HashPtrToSeqNum) {
|
||||
// Get an iterator to point to the insertion location
|
||||
BasicBlock::iterator BBI = --BB->end();
|
||||
ReturnInst &Ret = cast<ReturnInst>(BB->back());
|
||||
ReturnInst *Ret = cast<ReturnInst>(BB->getTerminator());
|
||||
|
||||
std::ostringstream OutStr;
|
||||
WriteAsOperand(OutStr, BB->getParent(), true);
|
||||
InsertPrintInst(0, BB, BBI, "LEAVING FUNCTION: " + OutStr.str(),
|
||||
InsertPrintInst(0, BB, Ret, "LEAVING FUNCTION: " + OutStr.str(),
|
||||
Printf, HashPtrToSeqNum);
|
||||
|
||||
// print the return value, if any
|
||||
if (BB->getParent()->getReturnType() != Type::VoidTy)
|
||||
InsertPrintInst(Ret.getReturnValue(), BB, BBI, " Returning: ",
|
||||
InsertPrintInst(Ret->getReturnValue(), BB, Ret, " Returning: ",
|
||||
Printf, HashPtrToSeqNum);
|
||||
}
|
||||
|
||||
@ -430,8 +390,9 @@ bool InsertTraceCode::runOnFunction(Function &F) {
|
||||
|
||||
// Push a pointer set for recording alloca'd pointers at entry.
|
||||
if (!DisablePtrHashing)
|
||||
InsertPushOnEntryFunc(&F, externalFuncs.PushOnEntryFunc);
|
||||
|
||||
new CallInst(externalFuncs.PushOnEntryFunc, vector<Value*>(), "",
|
||||
F.getEntryNode().begin());
|
||||
|
||||
for (Function::iterator BB = F.begin(); BB != F.end(); ++BB) {
|
||||
if (isa<ReturnInst>(BB->getTerminator()))
|
||||
exitBlocks.push_back(BB); // record this as an exit block
|
||||
@ -451,8 +412,8 @@ bool InsertTraceCode::runOnFunction(Function &F) {
|
||||
|
||||
// Release all recorded pointers before RETURN. Do this LAST!
|
||||
if (!DisablePtrHashing)
|
||||
InsertReleaseRecordedInst(exitBlocks[i],
|
||||
externalFuncs.ReleaseOnReturnFunc);
|
||||
new CallInst(externalFuncs.ReleaseOnReturnFunc, vector<Value*>(), "",
|
||||
exitBlocks[i]->getTerminator());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -179,8 +179,7 @@ static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI,
|
||||
}
|
||||
|
||||
GetElementPtrInst *GEP = new GetElementPtrInst(SrcPtr, Indices,
|
||||
AddOp2->getName());
|
||||
BI = ++BB->getInstList().insert(BI, GEP);
|
||||
AddOp2->getName(), BI);
|
||||
|
||||
Instruction *NCI = new CastInst(GEP, AddOp1->getType());
|
||||
ReplaceInstWithInst(BB->getInstList(), BI, NCI);
|
||||
@ -354,11 +353,11 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||
if (ElTy) {
|
||||
PRINT_PEEPHOLE1("cast-for-first:in", CI);
|
||||
|
||||
std::string Name = CI->getName(); CI->setName("");
|
||||
|
||||
// Insert the new T cast instruction... stealing old T's name
|
||||
GetElementPtrInst *GEP = new GetElementPtrInst(Src, Indices,
|
||||
CI->getName());
|
||||
CI->setName("");
|
||||
BI = ++BB->getInstList().insert(BI, GEP);
|
||||
Name, BI);
|
||||
|
||||
// Make the old cast instruction reference the new GEP instead of
|
||||
// the old src value.
|
||||
@ -397,10 +396,9 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||
PRINT_PEEPHOLE3("st-src-cast:in ", Pointer, Val, SI);
|
||||
|
||||
// Insert the new T cast instruction... stealing old T's name
|
||||
std::string Name(CI->getName()); CI->setName("");
|
||||
CastInst *NCI = new CastInst(Val, CSPT->getElementType(),
|
||||
CI->getName());
|
||||
CI->setName("");
|
||||
BI = ++BB->getInstList().insert(BI, NCI);
|
||||
Name, BI);
|
||||
|
||||
// Replace the old store with a new one!
|
||||
ReplaceInstWithInst(BB->getInstList(), BI,
|
||||
@ -436,11 +434,10 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||
PRINT_PEEPHOLE2("load-src-cast:in ", Pointer, LI);
|
||||
|
||||
// Create the new load instruction... loading the pre-casted value
|
||||
LoadInst *NewLI = new LoadInst(CastSrc, LI->getName());
|
||||
LoadInst *NewLI = new LoadInst(CastSrc, LI->getName(), BI);
|
||||
|
||||
// Insert the new T cast instruction... stealing old T's name
|
||||
CastInst *NCI = new CastInst(NewLI, LI->getType(), CI->getName());
|
||||
BI = ++BB->getInstList().insert(BI, NewLI);
|
||||
|
||||
// Replace the old store with a new one!
|
||||
ReplaceInstWithInst(BB->getInstList(), BI, NCI);
|
||||
|
@ -18,14 +18,13 @@
|
||||
#include "llvm/Pass.h"
|
||||
#include "Support/StatisticReporter.h"
|
||||
|
||||
static Statistic<> NumAdded("lowerrefs\t\t- New instructions added");
|
||||
|
||||
namespace {
|
||||
struct DecomposePass : public BasicBlockPass {
|
||||
virtual bool runOnBasicBlock(BasicBlock &BB);
|
||||
Statistic<> NumAdded("lowerrefs\t\t- # of getelementptr instructions added");
|
||||
|
||||
private:
|
||||
static bool decomposeArrayRef(BasicBlock::iterator &BBI);
|
||||
class DecomposePass : public BasicBlockPass {
|
||||
static bool decomposeArrayRef(GetElementPtrInst &GEP);
|
||||
public:
|
||||
virtual bool runOnBasicBlock(BasicBlock &BB);
|
||||
};
|
||||
|
||||
RegisterOpt<DecomposePass> X("lowerrefs", "Decompose multi-dimensional "
|
||||
@ -47,23 +46,15 @@ DecomposePass::runOnBasicBlock(BasicBlock &BB)
|
||||
{
|
||||
bool Changed = false;
|
||||
for (BasicBlock::iterator II = BB.begin(); II != BB.end(); ) {
|
||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&*II))
|
||||
if (GEP->getNumIndices() >= 2) {
|
||||
Changed |= decomposeArrayRef(II); // always modifies II
|
||||
continue;
|
||||
}
|
||||
Instruction *I = II;
|
||||
++II;
|
||||
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I))
|
||||
if (GEP->getNumIndices() >= 2)
|
||||
Changed |= decomposeArrayRef(*GEP); // always modifies II
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
||||
// Check for a constant (uint) 0.
|
||||
inline bool
|
||||
IsZero(Value* idx)
|
||||
{
|
||||
return (isa<ConstantInt>(idx) && cast<ConstantInt>(idx)->isNullValue());
|
||||
}
|
||||
|
||||
// For any GetElementPtrInst with 2 or more array and structure indices:
|
||||
//
|
||||
// opCode CompositeType* P, [uint|ubyte] idx1, ..., [uint|ubyte] idxN
|
||||
@ -86,17 +77,11 @@ IsZero(Value* idx)
|
||||
// Return value: true if the instruction was replaced; false otherwise.
|
||||
//
|
||||
bool
|
||||
DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI)
|
||||
DecomposePass::decomposeArrayRef(GetElementPtrInst &GEP)
|
||||
{
|
||||
GetElementPtrInst &GEP = cast<GetElementPtrInst>(*BBI);
|
||||
BasicBlock *BB = GEP.getParent();
|
||||
Value *LastPtr = GEP.getPointerOperand();
|
||||
|
||||
// Remove the instruction from the stream
|
||||
BB->getInstList().remove(BBI);
|
||||
|
||||
// The vector of new instructions to be created
|
||||
std::vector<Instruction*> NewInsts;
|
||||
Instruction *InsertPoint = GEP.getNext(); // Insert before the next insn
|
||||
|
||||
// Process each index except the last one.
|
||||
User::const_op_iterator OI = GEP.idx_begin(), OE = GEP.idx_end();
|
||||
@ -105,16 +90,17 @@ DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI)
|
||||
|
||||
// If this is the first index and is 0, skip it and move on!
|
||||
if (OI == GEP.idx_begin()) {
|
||||
if (IsZero(*OI)) continue;
|
||||
} else
|
||||
if (*OI == ConstantInt::getNullValue((*OI)->getType()))
|
||||
continue;
|
||||
} else {
|
||||
// Not the first index: include initial [0] to deref the last ptr
|
||||
Indices.push_back(Constant::getNullValue(Type::UIntTy));
|
||||
}
|
||||
|
||||
Indices.push_back(*OI);
|
||||
|
||||
// New Instruction: nextPtr1 = GetElementPtr LastPtr, Indices
|
||||
LastPtr = new GetElementPtrInst(LastPtr, Indices, "ptr1");
|
||||
NewInsts.push_back(cast<Instruction>(LastPtr));
|
||||
LastPtr = new GetElementPtrInst(LastPtr, Indices, "ptr1", InsertPoint);
|
||||
++NumAdded;
|
||||
}
|
||||
|
||||
@ -127,20 +113,13 @@ DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI)
|
||||
Indices.push_back(Constant::getNullValue(Type::UIntTy));
|
||||
Indices.push_back(*OI);
|
||||
|
||||
Instruction *NewI = new GetElementPtrInst(LastPtr, Indices, GEP.getName());
|
||||
NewInsts.push_back(NewI);
|
||||
Value *NewVal = new GetElementPtrInst(LastPtr, Indices, GEP.getName(),
|
||||
InsertPoint);
|
||||
|
||||
// Replace all uses of the old instruction with the new
|
||||
GEP.replaceAllUsesWith(NewI);
|
||||
GEP.replaceAllUsesWith(NewVal);
|
||||
|
||||
// Now delete the old instruction...
|
||||
delete &GEP;
|
||||
|
||||
// Insert all of the new instructions...
|
||||
BB->getInstList().insert(BBI, NewInsts.begin(), NewInsts.end());
|
||||
|
||||
// Advance the iterator to the instruction following the one just inserted...
|
||||
BBI = NewInsts.back();
|
||||
++BBI;
|
||||
// Now remove and delete the old instruction...
|
||||
BB->getInstList().erase(&GEP);
|
||||
return true;
|
||||
}
|
||||
|
@ -25,11 +25,8 @@ namespace {
|
||||
// name...
|
||||
//
|
||||
static Instruction *InsertCast(Value *Val, const Type *Ty,
|
||||
BasicBlock::iterator It) {
|
||||
Instruction *Cast = new CastInst(Val, Ty);
|
||||
if (Val->hasName()) Cast->setName(Val->getName()+"-casted");
|
||||
It->getParent()->getInstList().insert(It, Cast);
|
||||
return Cast;
|
||||
Instruction *InsertBefore) {
|
||||
return new CastInst(Val, Ty, Val->getName()+"-casted", InsertBefore);
|
||||
}
|
||||
|
||||
static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
||||
@ -75,19 +72,14 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
||||
// Okay, we want to convert other induction variables to use a cannonical
|
||||
// indvar. If we don't have one, add one now...
|
||||
if (!Cannonical) {
|
||||
// Create the PHI node for the new induction variable
|
||||
PHINode *PN = new PHINode(Type::UIntTy, "cann-indvar");
|
||||
|
||||
// Insert the phi node at the end of the other phi nodes...
|
||||
AfterPHIIt = ++Header->getInstList().insert(AfterPHIIt, PN);
|
||||
// Create the PHI node for the new induction variable, and insert the phi
|
||||
// node at the end of the other phi nodes...
|
||||
PHINode *PN = new PHINode(Type::UIntTy, "cann-indvar", AfterPHIIt);
|
||||
|
||||
// Create the increment instruction to add one to the counter...
|
||||
Instruction *Add = BinaryOperator::create(Instruction::Add, PN,
|
||||
ConstantUInt::get(Type::UIntTy,1),
|
||||
"add1-indvar");
|
||||
|
||||
// Insert the add instruction after all of the PHI nodes...
|
||||
Header->getInstList().insert(AfterPHIIt, Add);
|
||||
"add1-indvar", AfterPHIIt);
|
||||
|
||||
// Figure out which block is incoming and which is the backedge for the loop
|
||||
BasicBlock *Incoming, *BackEdgeBlock;
|
||||
@ -147,9 +139,7 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
||||
IV->Step = InsertCast(IV->Step, IVTy, AfterPHIIt);
|
||||
|
||||
Val = BinaryOperator::create(Instruction::Mul, Val, IV->Step,
|
||||
IV->Phi->getName()+"-scale");
|
||||
// Insert the phi node at the end of the other phi nodes...
|
||||
Header->getInstList().insert(AfterPHIIt, Val);
|
||||
IV->Phi->getName()+"-scale", AfterPHIIt);
|
||||
}
|
||||
|
||||
// If the start != 0
|
||||
@ -160,11 +150,9 @@ static bool TransformLoop(LoopInfo *Loops, Loop *Loop) {
|
||||
if (IV->Start->getType() != IVTy)
|
||||
IV->Start = InsertCast(IV->Start, IVTy, AfterPHIIt);
|
||||
|
||||
// Insert the instruction after the phi nodes...
|
||||
Val = BinaryOperator::create(Instruction::Add, Val, IV->Start,
|
||||
IV->Phi->getName()+"-offset");
|
||||
|
||||
// Insert the phi node at the end of the other phi nodes...
|
||||
Header->getInstList().insert(AfterPHIIt, Val);
|
||||
IV->Phi->getName()+"-offset", AfterPHIIt);
|
||||
}
|
||||
|
||||
// If the PHI node has a different type than val is, insert a cast now...
|
||||
|
@ -180,12 +180,9 @@ static Value *NegateValue(Value *V, BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||
// adding it now, we are assured that the neg instructions we just
|
||||
// inserted dominate the instruction we are about to insert after them.
|
||||
//
|
||||
BasicBlock::iterator NBI = cast<Instruction>(RHS);
|
||||
|
||||
Instruction *Add =
|
||||
BinaryOperator::create(Instruction::Add, LHS, RHS, I->getName()+".neg");
|
||||
BB->getInstList().insert(++NBI, Add); // Add to the basic block...
|
||||
return Add;
|
||||
return BinaryOperator::create(Instruction::Add, LHS, RHS,
|
||||
I->getName()+".neg",
|
||||
cast<Instruction>(RHS)->getNext());
|
||||
}
|
||||
|
||||
// Insert a 'neg' instruction that subtracts the value from zero to get the
|
||||
@ -194,8 +191,8 @@ static Value *NegateValue(Value *V, BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||
Instruction *Neg =
|
||||
BinaryOperator::create(Instruction::Sub,
|
||||
Constant::getNullValue(V->getType()), V,
|
||||
V->getName()+".neg");
|
||||
BI = BB->getInstList().insert(BI, Neg); // Add to the basic block...
|
||||
V->getName()+".neg", BI);
|
||||
--BI;
|
||||
return Neg;
|
||||
}
|
||||
|
||||
@ -220,8 +217,9 @@ bool Reassociate::ReassociateBB(BasicBlock *BB) {
|
||||
// Insert a new temporary instruction... (A+B)+C
|
||||
BinaryOperator *Tmp = BinaryOperator::create(I->getOpcode(), LHSI,
|
||||
RHSI->getOperand(0),
|
||||
RHSI->getName()+".ra");
|
||||
BI = BB->getInstList().insert(BI, Tmp); // Add to the basic block...
|
||||
RHSI->getName()+".ra",
|
||||
BI);
|
||||
BI = Tmp;
|
||||
I->setOperand(0, Tmp);
|
||||
I->setOperand(1, RHSI->getOperand(1));
|
||||
|
||||
|
@ -141,35 +141,25 @@ const Type *ConvertableToGEP(const Type *Ty, Value *OffsetVal,
|
||||
|
||||
if (BI) { // Generate code?
|
||||
BasicBlock *BB = (*BI)->getParent();
|
||||
if (Expr.Var->getType() != Type::UIntTy) {
|
||||
CastInst *IdxCast = new CastInst(Expr.Var, Type::UIntTy);
|
||||
if (Expr.Var->hasName())
|
||||
IdxCast->setName(Expr.Var->getName()+"-idxcast");
|
||||
*BI = ++BB->getInstList().insert(*BI, IdxCast);
|
||||
Expr.Var = IdxCast;
|
||||
}
|
||||
if (Expr.Var->getType() != Type::UIntTy)
|
||||
Expr.Var = new CastInst(Expr.Var, Type::UIntTy,
|
||||
Expr.Var->getName()+"-idxcast", *BI);
|
||||
|
||||
if (ScaleAmt && ScaleAmt != 1) {
|
||||
// If we have to scale up our index, do so now
|
||||
Value *ScaleAmtVal = ConstantUInt::get(Type::UIntTy,
|
||||
(unsigned)ScaleAmt);
|
||||
Instruction *Scaler = BinaryOperator::create(Instruction::Mul,
|
||||
Expr.Var, ScaleAmtVal);
|
||||
if (Expr.Var->hasName())
|
||||
Scaler->setName(Expr.Var->getName()+"-scale");
|
||||
|
||||
*BI = ++BB->getInstList().insert(*BI, Scaler);
|
||||
Expr.Var = Scaler;
|
||||
Expr.Var = BinaryOperator::create(Instruction::Mul, Expr.Var,
|
||||
ScaleAmtVal,
|
||||
Expr.Var->getName()+"-scale",*BI);
|
||||
}
|
||||
|
||||
if (Index) { // Add an offset to the index
|
||||
Value *IndexAmt = ConstantUInt::get(Type::UIntTy, (unsigned)Index);
|
||||
Instruction *Offseter = BinaryOperator::create(Instruction::Add,
|
||||
Expr.Var, IndexAmt);
|
||||
if (Expr.Var->hasName())
|
||||
Offseter->setName(Expr.Var->getName()+"-offset");
|
||||
*BI = ++BB->getInstList().insert(*BI, Offseter);
|
||||
Expr.Var = Offseter;
|
||||
Expr.Var = BinaryOperator::create(Instruction::Add, Expr.Var,
|
||||
IndexAmt,
|
||||
Expr.Var->getName()+"-offset",
|
||||
*BI);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user