summaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-12-14 16:37:52 +0000
committerChris Lattner <sabre@nondot.org>2001-12-14 16:37:52 +0000
commitd55438085090886a1c7ddc37159b1cfb406fbce4 (patch)
treebb0f12f2559c1862e29cb2a0a5845a9329833877 /lib/Transforms
parent97ac4ee02e9554ada879d0f5b6ec49c7de4cecfb (diff)
downloadllvm-d55438085090886a1c7ddc37159b1cfb406fbce4.tar.gz
llvm-d55438085090886a1c7ddc37159b1cfb406fbce4.tar.bz2
llvm-d55438085090886a1c7ddc37159b1cfb406fbce4.tar.xz
* Support pointer indexing
* Unsized arrays are a thing of the past, remove DoInsertArrayCast family * Remove cases were we would get into infinite loops because we would insert a cast which would then be removed, inserting a different cast, ad infinitum... * Remove some code that should be redundant with ExprTypeConvert code git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1465 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/LevelRaise.cpp243
1 files changed, 33 insertions, 210 deletions
diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp
index c672c4e501..e47eb90642 100644
--- a/lib/Transforms/LevelRaise.cpp
+++ b/lib/Transforms/LevelRaise.cpp
@@ -78,18 +78,6 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
vector<Value*> Indices;
Value *Src = CI->getOperand(0);
const Type *Result = ConvertableToGEP(DestPTy, Src, Indices, &BI);
- const PointerType *UsedType = DestPTy;
-
- // If we fail, check to see if we have an pointer source type that, if
- // converted to an unsized array type, would work. In this case, we propogate
- // the cast forward to the input of the add instruction.
- //
- if (Result == 0 && getPointedToComposite(DestPTy) == 0) {
- // Make an unsized array and try again...
- UsedType = PointerType::get(ArrayType::get(DestPTy->getElementType()));
- Result = ConvertableToGEP(UsedType, Src, Indices, &BI);
- }
-
if (Result == 0) return false; // Not convertable...
PRINT_PEEPHOLE2("cast-add-to-gep:in", Src, CI);
@@ -109,13 +97,6 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
BasicBlock::iterator AddIt = find(BB->getInstList().begin(),
BB->getInstList().end(), I);
- if (UsedType != DestPTy) {
- // Insert a cast of the incoming value to something addressable...
- CastInst *C = new CastInst(OtherPtr, UsedType, OtherPtr->getName());
- AddIt = BB->getInstList().insert(AddIt, C)+1;
- OtherPtr = C;
- }
-
GetElementPtrInst *GEP = new GetElementPtrInst(OtherPtr, Indices);
PRINT_PEEPHOLE1("cast-add-to-gep:i", I);
@@ -223,46 +204,48 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
// Check to see if it's a cast of an instruction that does not depend on the
// specific type of the operands to do it's job.
if (!isReinterpretingCast(CI)) {
- // Check to see if we can convert the source of the cast to match the
- // destination type of the cast...
- //
ValueTypeCache ConvertedTypes;
- if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes)) {
- PRINT_PEEPHOLE2("CAST-DEST-EXPR-CONV:in ", Src, CI);
+ // Check to see if we can convert the users of the cast value to match the
+ // source type of the cast...
+ //
+ ConvertedTypes[CI] = CI->getType(); // Make sure the cast doesn't change
+ if (ExpressionConvertableToType(Src, DestTy, ConvertedTypes)) {
+ PRINT_PEEPHOLE3("CAST-SRC-EXPR-CONV:in ", Src, CI, BB->getParent());
+
#ifdef DEBUG_PEEPHOLE_INSTS
- cerr << "\nCONVERTING EXPR TYPE:\n";
+ cerr << "\nCONVERTING SRC EXPR TYPE:\n";
#endif
ValueMapCache ValueMap;
- ConvertValueToNewType(CI, Src, ValueMap); // This will delete CI!
+ Value *E = ConvertExpressionToType(Src, DestTy, ValueMap);
+ if (Constant *CPV = dyn_cast<Constant>(E))
+ CI->replaceAllUsesWith(CPV);
BI = BB->begin(); // Rescan basic block. BI might be invalidated.
- PRINT_PEEPHOLE1("CAST-DEST-EXPR-CONV:out", Src);
+ PRINT_PEEPHOLE1("CAST-SRC-EXPR-CONV:out", E);
#ifdef DEBUG_PEEPHOLE_INSTS
- cerr << "DONE CONVERTING EXPR TYPE: \n\n";// << BB->getParent();
+ cerr << "DONE CONVERTING SRC EXPR TYPE: \n" << BB->getParent();
#endif
return true;
}
- // Check to see if we can convert the users of the cast value to match the
- // source type of the cast...
+ // Check to see if we can convert the source of the cast to match the
+ // destination type of the cast...
//
ConvertedTypes.clear();
- if (ExpressionConvertableToType(Src, DestTy, ConvertedTypes)) {
- PRINT_PEEPHOLE2("CAST-SRC-EXPR-CONV:in ", Src, CI);
-
+ if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes)) {
+ PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent());
+
#ifdef DEBUG_PEEPHOLE_INSTS
- cerr << "\nCONVERTING SRC EXPR TYPE:\n";
+ cerr << "\nCONVERTING EXPR TYPE:\n";
#endif
ValueMapCache ValueMap;
- Value *E = ConvertExpressionToType(Src, DestTy, ValueMap);
- if (Constant *CPV = dyn_cast<Constant>(E))
- CI->replaceAllUsesWith(CPV);
+ ConvertValueToNewType(CI, Src, ValueMap); // This will delete CI!
BI = BB->begin(); // Rescan basic block. BI might be invalidated.
- PRINT_PEEPHOLE1("CAST-SRC-EXPR-CONV:out", E);
+ PRINT_PEEPHOLE1("CAST-DEST-EXPR-CONV:out", Src);
#ifdef DEBUG_PEEPHOLE_INSTS
- cerr << "DONE CONVERTING SRC EXPR TYPE: \n\n";// << BB->getParent();
+ cerr << "DONE CONVERTING EXPR TYPE: \n\n" << BB->getParent();
#endif
return true;
}
@@ -317,8 +300,8 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
// Build the index vector, full of all zeros
vector<Value*> Indices;
-
- while (CurCTy) {
+ Indices.push_back(ConstantUInt::get(Type::UIntTy, 0));
+ while (CurCTy && !isa<PointerType>(CurCTy)) {
if (const StructType *CurSTy = dyn_cast<StructType>(CurCTy)) {
// Check for a zero element struct type... if we have one, bail.
if (CurSTy->getElementTypes().size() == 0) break;
@@ -371,27 +354,6 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
Value *Pointer = SI->getPointerOperand();
// Peephole optimize the following instructions:
- // %t1 = getelementptr {<...>} * %StructPtr, <element indices>
- // store <elementty> %v, <elementty> * %t1
- //
- // Into: store <elementty> %v, {<...>} * %StructPtr, <element indices>
- //
- if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Pointer)) {
- // Append any indices that the store instruction has onto the end of the
- // ones that the GEP is carrying...
- //
- vector<Value*> Indices(GEP->copyIndices());
- Indices.insert(Indices.end(), SI->idx_begin(), SI->idx_end());
-
- PRINT_PEEPHOLE2("gep-store:in", GEP, SI);
- ReplaceInstWithInst(BB->getInstList(), BI,
- SI = new StoreInst(Val, GEP->getPointerOperand(),
- Indices));
- PRINT_PEEPHOLE1("gep-store:out", SI);
- return true;
- }
-
- // Peephole optimize the following instructions:
// %t = cast <T1>* %P to <T2> * ;; If T1 is losslessly convertable to T2
// store <T2> %V, <T2>* %t
//
@@ -399,6 +361,11 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
// %t = cast <T2> %V to <T1>
// store <T1> %t2, <T1>* %P
//
+ // Note: This is not taken care of by expr conversion because there might
+ // not be a cast available for the store to convert the incoming value of.
+ // This code is basically here to make sure that pointers don't have casts
+ // if possible.
+ //
if (CastInst *CI = dyn_cast<CastInst>(Pointer))
if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
if (PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
@@ -420,32 +387,6 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
return true;
}
-
- } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
-#if 0
- Value *Pointer = LI->getPointerOperand();
-
- // Peephole optimize the following instructions:
- // %t1 = getelementptr {<...>} * %StructPtr, <element indices>
- // %V = load <elementty> * %t1
- //
- // Into: load {<...>} * %StructPtr, <element indices>
- //
- if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Pointer)) {
- // Append any indices that the load instruction has onto the end of the
- // ones that the GEP is carrying...
- //
- vector<Value*> Indices(GEP->copyIndices());
- Indices.insert(Indices.end(), LI->idx_begin(), LI->idx_end());
-
- PRINT_PEEPHOLE2("gep-load:in", GEP, LI);
- ReplaceInstWithInst(BB->getInstList(), BI,
- LI = new LoadInst(GEP->getPointerOperand(),
- Indices));
- PRINT_PEEPHOLE1("gep-load:out", LI);
- return true;
- }
-#endif
} else if (I->getOpcode() == Instruction::Add &&
isa<CastInst>(I->getOperand(1))) {
@@ -469,6 +410,9 @@ static bool DoRaisePass(Method *M) {
BasicBlock::InstListType &BIL = BB->getInstList();
for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) {
+#if DEBUG_PEEPHOLE_INSTS
+ cerr << "Processing: " << *BI;
+#endif
if (opt::DeadCodeElimination::dceInstruction(BIL, BI) ||
opt::ConstantPropogation::doConstantPropogation(BB, BI)) {
Changed = true;
@@ -487,127 +431,6 @@ static bool DoRaisePass(Method *M) {
-// DoInsertArrayCast - If the argument value has a pointer type, and if the
-// argument value is used as an array, insert a cast before the specified
-// basic block iterator that casts the value to an array pointer. Return the
-// new cast instruction (in the CastResult var), or null if no cast is inserted.
-//
-static bool DoInsertArrayCast(Value *V, BasicBlock *BB,
- BasicBlock::iterator InsertBefore) {
- const PointerType *ThePtrType = dyn_cast<PointerType>(V->getType());
- if (!ThePtrType) return false;
-
- const Type *ElTy = ThePtrType->getElementType();
- if (isa<MethodType>(ElTy) ||
- (isa<ArrayType>(ElTy) && cast<ArrayType>(ElTy)->isUnsized()))
- return false;
-
- unsigned ElementSize = TD.getTypeSize(ElTy);
- bool InsertCast = false;
-
- for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
- Instruction *Inst = cast<Instruction>(*I);
- switch (Inst->getOpcode()) {
- case Instruction::Cast: // There is already a cast instruction!
- if (const PointerType *PT = dyn_cast<const PointerType>(Inst->getType()))
- if (const ArrayType *AT = dyn_cast<const ArrayType>(PT->getElementType()))
- if (AT->getElementType() == ThePtrType->getElementType()) {
- // Cast already exists! Don't mess around with it.
- return false; // No changes made to program though...
- }
- break;
- case Instruction::Add: { // Analyze pointer arithmetic...
- Value *OtherOp = Inst->getOperand(Inst->getOperand(0) == V);
- analysis::ExprType Expr = analysis::ClassifyExpression(OtherOp);
-
- // This looks like array addressing iff:
- // A. The constant of the index is larger than the size of the element
- // type.
- // B. The scale factor is >= the size of the type.
- //
- if (Expr.Offset && getConstantValue(Expr.Offset) >= (int)ElementSize) // A
- InsertCast = true;
-
- if (Expr.Scale && getConstantValue(Expr.Scale) >= (int)ElementSize) // B
- InsertCast = true;
-
- break;
- }
- default: break; // Not an interesting use...
- }
- }
-
- if (!InsertCast) return false; // There is no reason to insert a cast!
-
- // Calculate the destination pointer type
- const PointerType *DestTy = PointerType::get(ArrayType::get(ElTy));
-
- // Check to make sure that all uses of the value can be converted over to use
- // the newly typed value.
- //
- ValueTypeCache ConvertedTypes;
- if (!ValueConvertableToType(V, DestTy, ConvertedTypes)) {
- cerr << "FAILED to convert types of values for " << V << " to " << DestTy << "\n";
- ConvertedTypes.clear();
- ValueConvertableToType(V, DestTy, ConvertedTypes);
- return false;
- }
- ConvertedTypes.clear();
-
- // Insert a cast!
- CastInst *TheCast =
- new CastInst(Constant::getNullConstant(V->getType()), DestTy, V->getName());
- BB->getInstList().insert(InsertBefore, TheCast);
-
-#ifdef DEBUG_PEEPHOLE_INSTS
- cerr << "Inserting cast for " << V << endl;
-#endif
-
- // Convert users of the old value over to use the cast result...
- ValueMapCache VMC;
- ConvertValueToNewType(V, TheCast, VMC);
-
- // The cast is the only thing that is allowed to reference the value...
- TheCast->setOperand(0, V);
-
-#ifdef DEBUG_PEEPHOLE_INSTS
- cerr << "Inserted ptr-array cast: " << TheCast;
-#endif
- return true; // Made a change!
-}
-
-
-// DoInsertArrayCasts - Loop over all "incoming" values in the specified method,
-// inserting a cast for pointer values that are used as arrays. For our
-// purposes, an incoming value is considered to be either a value that is
-// either a method parameter, or a pointer returned from a function call.
-//
-static bool DoInsertArrayCasts(Method *M) {
- assert(!M->isExternal() && "Can't handle external methods!");
-
- // Insert casts for all arguments to the function...
- bool Changed = false;
- BasicBlock *CurBB = M->front();
-
- for (Method::ArgumentListType::iterator AI = M->getArgumentList().begin(),
- AE = M->getArgumentList().end(); AI != AE; ++AI) {
-
- Changed |= DoInsertArrayCast(*AI, CurBB, CurBB->begin());
- }
-
- // TODO: insert casts for alloca, malloc, and function call results. Also,
- // look for pointers that already have casts, to add to the map.
-
-#ifdef DEBUG_PEEPHOLE_INSTS
- if (Changed) cerr << "Inserted casts:\n" << M;
-#endif
-
- return Changed;
-}
-
-
-
-
// RaisePointerReferences::doit - Raise a method representation to a higher
// level.
//
@@ -627,10 +450,10 @@ bool RaisePointerReferences::doit(Method *M) {
#ifdef DEBUG_PEEPHOLE_INSTS
cerr << "Looping: \n" << M;
#endif
- LocalChange = DoInsertArrayCasts(M);
// Iterate over the method, refining it, until it converges on a stable
// state
+ LocalChange = false;
while (DoRaisePass(M)) LocalChange = true;
Changed |= LocalChange;