aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/LevelRaise.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-11-04 07:42:17 +0000
committerChris Lattner <sabre@nondot.org>2001-11-04 07:42:17 +0000
commitb96939519b4e2852e8578cc03cddb8f94b23f819 (patch)
treec5cdbdee1314dc97b9c56b593bbe4b8b27269354 /lib/Transforms/LevelRaise.cpp
parentab9f21f4c4ce5224408b8566bdf3773e5b593367 (diff)
Add transformations for Load and GetElementPtr. Fix broken transform with shr.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1118 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/LevelRaise.cpp')
-rw-r--r--lib/Transforms/LevelRaise.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp
index 039bfd20d7..b5f7056892 100644
--- a/lib/Transforms/LevelRaise.cpp
+++ b/lib/Transforms/LevelRaise.cpp
@@ -221,8 +221,48 @@ static bool ExpressionConvertableToType(Value *V, const Type *Ty) {
return ExpressionConvertableToType(I->getOperand(0), Ty) &&
ExpressionConvertableToType(I->getOperand(1), Ty);
case Instruction::Shl:
+ return ExpressionConvertableToType(I->getOperand(0), Ty);
case Instruction::Shr:
+ if (Ty->isSigned() != V->getType()->isSigned()) return false;
return ExpressionConvertableToType(I->getOperand(0), Ty);
+
+ case Instruction::Load: {
+ LoadInst *LI = cast<LoadInst>(I);
+ if (LI->hasIndices()) return false;
+ return ExpressionConvertableToType(LI->getPtrOperand(),
+ PointerType::get(Ty));
+ }
+ case Instruction::GetElementPtr: {
+ // GetElementPtr's are directly convertable to a pointer type if they have
+ // a number of zeros at the end. Because removing these values does not
+ // change the logical offset of the GEP, it is okay and fair to remove them.
+ // This can change this:
+ // %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0 ; <%List **>
+ // %t2 = cast %List * * %t1 to %List *
+ // into
+ // %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
+ //
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+ const PointerType *PTy = dyn_cast<PointerType>(Ty);
+ if (!PTy) return false;
+
+ // Check to see if there are zero elements that we can remove from the
+ // index array. If there are, check to see if removing them causes us to
+ // get to the right type...
+ //
+ vector<ConstPoolVal*> Indices = GEP->getIndexVec();
+ const Type *BaseType = GEP->getPtrOperand()->getType();
+
+ while (Indices.size() &&
+ cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
+ Indices.pop_back();
+ const Type *ElTy = GetElementPtrInst::getIndexedType(BaseType, Indices,
+ true);
+ if (ElTy == PTy->getValueType())
+ return true; // Found a match!!
+ }
+ break; // No match, maybe next time.
+ }
}
return false;
}
@@ -269,6 +309,50 @@ static Value *ConvertExpressionToType(Value *V, const Type *Ty) {
I->getOperand(1), Name);
break;
+ case Instruction::Load: {
+ LoadInst *LI = cast<LoadInst>(I);
+ assert(!LI->hasIndices());
+ Res = new LoadInst(ConvertExpressionToType(LI->getPtrOperand(),
+ PointerType::get(Ty)), Name);
+ break;
+ }
+
+ case Instruction::GetElementPtr: {
+ // GetElementPtr's are directly convertable to a pointer type if they have
+ // a number of zeros at the end. Because removing these values does not
+ // change the logical offset of the GEP, it is okay and fair to remove them.
+ // This can change this:
+ // %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0 ; <%List **>
+ // %t2 = cast %List * * %t1 to %List *
+ // into
+ // %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
+ //
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+
+ // Check to see if there are zero elements that we can remove from the
+ // index array. If there are, check to see if removing them causes us to
+ // get to the right type...
+ //
+ vector<ConstPoolVal*> Indices = GEP->getIndexVec();
+ const Type *BaseType = GEP->getPtrOperand()->getType();
+ const Type *PVTy = cast<PointerType>(Ty)->getValueType();
+ Res = 0;
+ while (Indices.size() &&
+ cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
+ Indices.pop_back();
+ if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) {
+ if (Indices.size() == 0) {
+ Res = new CastInst(GEP->getPtrOperand(), BaseType); // NOOP
+ } else {
+ Res = new GetElementPtrInst(GEP->getPtrOperand(), Indices, Name);
+ }
+ break;
+ }
+ }
+ assert(Res && "Didn't find match!");
+ break; // No match, maybe next time.
+ }
+
default:
assert(0 && "Expression convertable, but don't know how to convert?");
return 0;
@@ -458,6 +542,18 @@ static bool PeepholeMallocInst(BasicBlock *BB, BasicBlock::iterator &BI) {
}
+// Peephole optimize the following instructions:
+// %t1 = cast int (uint) * %reg111 to uint (...) *
+// %t2 = call uint (...) * %cast111( uint %key )
+//
+// Into: %t3 = call int (uint) * %reg111( uint %key )
+// %t2 = cast int %t3 to uint
+//
+static bool PeepholeCallInst(BasicBlock *BB, BasicBlock::iterator &BI) {
+ CallInst *CI = cast<CallInst>(*BI);
+ return false;
+}
+
static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
Instruction *I = *BI;
@@ -596,6 +692,9 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
} else if (MallocInst *MI = dyn_cast<MallocInst>(I)) {
if (PeepholeMallocInst(BB, BI)) return true;
+ } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (PeepholeCallInst(BB, BI)) return true;
+
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
Value *Val = SI->getOperand(0);
Value *Pointer = SI->getPtrOperand();