From 7ba98a90008727e2fa0dfc1787cad71e1b6021eb Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sat, 3 Feb 2007 23:15:56 +0000 Subject: For PR1072: Removing -raise has neglible positive or negative side effects so we are opting to remove it. See the PR for comparison details. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33844 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/LinkAllPasses.h | 1 - include/llvm/Transforms/Scalar.h | 8 - lib/Transforms/ExprTypeConvert.cpp | 998 --------------------- lib/Transforms/LevelRaise.cpp | 452 ---------- lib/Transforms/Makefile | 2 - lib/Transforms/TransformInternals.cpp | 92 -- test/Transforms/LevelRaise/.cvsignore | 3 - .../LevelRaise/2002-02-14-BadAssertion.ll | 19 - test/Transforms/LevelRaise/2002-03-11-Calls.ll | 15 - .../LevelRaise/2002-03-14-ConvertableToGEPHang.ll | 24 - test/Transforms/LevelRaise/2002-03-20-Crash.ll | 20 - .../LevelRaise/2002-03-21-MissedRaise.ll | 24 - .../LevelRaise/2002-03-21-MissedRaise2.ll | 29 - .../LevelRaise/2002-03-21-MissedRaise3.ll | 19 - .../LevelRaise/2002-04-16-MissedRaise.ll | 22 - .../LevelRaise/2002-05-02-BadCastElimination.ll | 24 - .../LevelRaise/2002-05-02-MissedRaise.ll | 20 - .../LevelRaise/2002-05-10-LoadPeephole.ll | 10 - .../LevelRaise/2002-05-23-MissedRaise.ll | 20 - .../LevelRaise/2002-07-16-MissedRaise.ll | 22 - .../Transforms/LevelRaise/2002-07-16-RaiseCrash.ll | 53 -- .../LevelRaise/2002-07-16-RaiseCrash2.ll | 12 - .../LevelRaise/2002-07-16-SourceAndDestCrash.ll | 21 - .../LevelRaise/2002-07-18-MissedAllocaRaise.ll | 11 - .../LevelRaise/2002-07-31-AssertionFailure.ll | 26 - .../LevelRaise/2002-09-10-PointerAdds.ll | 9 - .../LevelRaise/2002-10-02-SignExtensionProblem.ll | 13 - .../Transforms/LevelRaise/2002-10-08-VarArgCall.ll | 9 - .../LevelRaise/2002-10-08-VarArgCallInfLoop.ll | 10 - .../LevelRaise/2002-11-04-ConstantSharing.ll | 12 - .../LevelRaise/2002-11-13-PointerFunction.ll | 10 - .../Transforms/LevelRaise/2003-01-22-GEPProblem.ll | 22 - .../Transforms/LevelRaise/2003-01-30-ShiftCrash.ll | 34 - test/Transforms/LevelRaise/2003-02-13-CallRaise.ll | 9 - test/Transforms/LevelRaise/2003-05-01-CallCast.ll | 8 - .../LevelRaise/2003-06-07-EmptyArrayTest.ll | 10 - .../LevelRaise/2003-06-25-ExprAnalysis.ll | 24 - .../LevelRaise/2003-11-28-IllegalTypeConversion.ll | 10 - test/Transforms/LevelRaise/dg.exp | 3 - tools/bugpoint/Makefile | 2 +- tools/opt/Makefile | 3 +- tools/opt/opt.cpp | 1 - 42 files changed, 2 insertions(+), 2134 deletions(-) delete mode 100644 lib/Transforms/ExprTypeConvert.cpp delete mode 100644 lib/Transforms/LevelRaise.cpp delete mode 100644 lib/Transforms/TransformInternals.cpp delete mode 100644 test/Transforms/LevelRaise/.cvsignore delete mode 100644 test/Transforms/LevelRaise/2002-02-14-BadAssertion.ll delete mode 100644 test/Transforms/LevelRaise/2002-03-11-Calls.ll delete mode 100644 test/Transforms/LevelRaise/2002-03-14-ConvertableToGEPHang.ll delete mode 100644 test/Transforms/LevelRaise/2002-03-20-Crash.ll delete mode 100644 test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll delete mode 100644 test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll delete mode 100644 test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll delete mode 100644 test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll delete mode 100644 test/Transforms/LevelRaise/2002-05-02-BadCastElimination.ll delete mode 100644 test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll delete mode 100644 test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll delete mode 100644 test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll delete mode 100644 test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll delete mode 100644 test/Transforms/LevelRaise/2002-07-16-RaiseCrash.ll delete mode 100644 test/Transforms/LevelRaise/2002-07-16-RaiseCrash2.ll delete mode 100644 test/Transforms/LevelRaise/2002-07-16-SourceAndDestCrash.ll delete mode 100644 test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll delete mode 100644 test/Transforms/LevelRaise/2002-07-31-AssertionFailure.ll delete mode 100644 test/Transforms/LevelRaise/2002-09-10-PointerAdds.ll delete mode 100644 test/Transforms/LevelRaise/2002-10-02-SignExtensionProblem.ll delete mode 100644 test/Transforms/LevelRaise/2002-10-08-VarArgCall.ll delete mode 100644 test/Transforms/LevelRaise/2002-10-08-VarArgCallInfLoop.ll delete mode 100644 test/Transforms/LevelRaise/2002-11-04-ConstantSharing.ll delete mode 100644 test/Transforms/LevelRaise/2002-11-13-PointerFunction.ll delete mode 100644 test/Transforms/LevelRaise/2003-01-22-GEPProblem.ll delete mode 100644 test/Transforms/LevelRaise/2003-01-30-ShiftCrash.ll delete mode 100644 test/Transforms/LevelRaise/2003-02-13-CallRaise.ll delete mode 100644 test/Transforms/LevelRaise/2003-05-01-CallCast.ll delete mode 100644 test/Transforms/LevelRaise/2003-06-07-EmptyArrayTest.ll delete mode 100644 test/Transforms/LevelRaise/2003-06-25-ExprAnalysis.ll delete mode 100644 test/Transforms/LevelRaise/2003-11-28-IllegalTypeConversion.ll delete mode 100644 test/Transforms/LevelRaise/dg.exp diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index eba96e63bc..01e049938d 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -96,7 +96,6 @@ namespace { (void) llvm::createDemoteRegisterToMemoryPass(); (void) llvm::createPruneEHPass(); (void) llvm::createRaiseAllocationsPass(); - (void) llvm::createRaisePointerReferencesPass(); (void) llvm::createReassociatePass(); (void) llvm::createSCCPPass(); (void) llvm::createScalarReplAggregatesPass(); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index ea5692b206..ff6fbf0b05 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -26,14 +26,6 @@ class PassInfo; class TerminatorInst; class TargetLowering; -//===----------------------------------------------------------------------===// -// -// RaisePointerReferences - Try to eliminate as many pointer arithmetic -// expressions as possible, by converting expressions to use getelementptr and -// friends. -// -FunctionPass *createRaisePointerReferencesPass(); - //===----------------------------------------------------------------------===// // // ConstantPropagation - A worklist driven constant propagation pass diff --git a/lib/Transforms/ExprTypeConvert.cpp b/lib/Transforms/ExprTypeConvert.cpp deleted file mode 100644 index 2b620aff78..0000000000 --- a/lib/Transforms/ExprTypeConvert.cpp +++ /dev/null @@ -1,998 +0,0 @@ -//===- ExprTypeConvert.cpp - Code to change an LLVM Expr Type -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the part of level raising that checks to see if it is -// possible to coerce an entire expression tree into a different type. If -// convertible, other routines from this file will do the conversion. -// -//===----------------------------------------------------------------------===// - -#include "TransformInternals.h" -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Debug.h" -#include -using namespace llvm; - -static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, - ValueTypeCache &ConvertedTypes, - const TargetData &TD); - -static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, - ValueMapCache &VMC, const TargetData &TD); - - -// ExpressionConvertibleToType - Return true if it is possible -bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty, - ValueTypeCache &CTMap, const TargetData &TD) { - // Expression type must be holdable in a register. - if (!Ty->isFirstClassType()) - return false; - - ValueTypeCache::iterator CTMI = CTMap.find(V); - if (CTMI != CTMap.end()) return CTMI->second == Ty; - - // If it's a constant... all constants can be converted to a different - // type. - // - if (isa(V) && !isa(V)) - return true; - - CTMap[V] = Ty; - if (V->getType() == Ty) return true; // Expression already correct type! - - Instruction *I = dyn_cast(V); - if (I == 0) return false; // Otherwise, we can't convert! - - switch (I->getOpcode()) { - case Instruction::BitCast: - if (!cast(I)->isLosslessCast()) - return false; - // We do not allow conversion of a cast that casts from a ptr to array - // of X to a *X. For example: cast [4 x %List *] * %val to %List * * - // - if (const PointerType *SPT = - dyn_cast(I->getOperand(0)->getType())) - if (const PointerType *DPT = dyn_cast(I->getType())) - if (const ArrayType *AT = dyn_cast(SPT->getElementType())) - if (AT->getElementType() == DPT->getElementType()) - return false; - // Otherwise it is a lossless cast and we can allow it - break; - - case Instruction::Add: - case Instruction::Sub: - if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false; - if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD) || - !ExpressionConvertibleToType(I->getOperand(1), Ty, CTMap, TD)) - return false; - break; - case Instruction::LShr: - case Instruction::AShr: - if (!Ty->isInteger()) return false; - if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD)) - return false; - break; - case Instruction::Shl: - if (!Ty->isInteger()) return false; - if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD)) - return false; - break; - - case Instruction::Load: { - LoadInst *LI = cast(I); - if (!ExpressionConvertibleToType(LI->getPointerOperand(), - PointerType::get(Ty), CTMap, TD)) - return false; - break; - } - case Instruction::PHI: { - PHINode *PN = cast(I); - // Be conservative if we find a giant PHI node. - if (PN->getNumIncomingValues() > 32) return false; - - for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) - if (!ExpressionConvertibleToType(PN->getIncomingValue(i), Ty, CTMap, TD)) - return false; - break; - } - - case Instruction::GetElementPtr: { - // GetElementPtr's are directly convertible 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(I); - const PointerType *PTy = dyn_cast(Ty); - if (!PTy) return false; // GEP must always return a pointer... - const Type *PVTy = PTy->getElementType(); - - // 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... - // - std::vector Indices(GEP->idx_begin(), GEP->idx_end()); - const Type *BaseType = GEP->getPointerOperand()->getType(); - const Type *ElTy = 0; - - while (!Indices.empty() && - Indices.back() == Constant::getNullValue(Indices.back()->getType())){ - Indices.pop_back(); - ElTy = GetElementPtrInst::getIndexedType(BaseType, Indices, true); - if (ElTy == PVTy) - break; // Found a match!! - ElTy = 0; - } - - if (ElTy) break; // Found a number of zeros we can strip off! - - // Otherwise, it could be that we have something like this: - // getelementptr [[sbyte] *] * %reg115, long %reg138 ; [sbyte]** - // and want to convert it into something like this: - // getelemenptr [[int] *] * %reg115, long %reg138 ; [int]** - // - if (GEP->getNumOperands() == 2 && - PTy->getElementType()->isSized() && - TD.getTypeSize(PTy->getElementType()) == - TD.getTypeSize(GEP->getType()->getElementType())) { - const PointerType *NewSrcTy = PointerType::get(PVTy); - if (!ExpressionConvertibleToType(I->getOperand(0), NewSrcTy, CTMap, TD)) - return false; - break; - } - - return false; // No match, maybe next time. - } - - case Instruction::Call: { - if (isa(I->getOperand(0))) - return false; // Don't even try to change direct calls. - - // If this is a function pointer, we can convert the return type if we can - // convert the source function pointer. - // - const PointerType *PT = cast(I->getOperand(0)->getType()); - const FunctionType *FT = cast(PT->getElementType()); - std::vector ArgTys(FT->param_begin(), FT->param_end()); - const FunctionType *NewTy = - FunctionType::get(Ty, ArgTys, FT->isVarArg()); - if (!ExpressionConvertibleToType(I->getOperand(0), - PointerType::get(NewTy), CTMap, TD)) - return false; - break; - } - default: - return false; - } - - // Expressions are only convertible if all of the users of the expression can - // have this value converted. This makes use of the map to avoid infinite - // recursion. - // - for (Value::use_iterator It = I->use_begin(), E = I->use_end(); It != E; ++It) - if (!OperandConvertibleToType(*It, I, Ty, CTMap, TD)) - return false; - - return true; -} - - -Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty, - ValueMapCache &VMC, const TargetData &TD) { - if (V->getType() == Ty) return V; // Already where we need to be? - - ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(V); - if (VMCI != VMC.ExprMap.end()) { - assert(VMCI->second->getType() == Ty); - - if (Instruction *I = dyn_cast(V)) - ValueHandle IHandle(VMC, I); // Remove I if it is unused now! - - return VMCI->second; - } - - DOUT << "CETT: " << (void*)V << " " << *V; - - Instruction *I = dyn_cast(V); - if (I == 0) { - Constant *CPV = cast(V); - // Constants are converted by constant folding the cast that is required. - // We assume here that all casts are implemented for constant prop. - // FIXME: This seems to work, but it is unclear why ZEXT is always the - // right choice here. - Instruction::CastOps opcode = CastInst::getCastOpcode(CPV, false, Ty,false); - Value *Result = ConstantExpr::getCast(opcode, CPV, Ty); - // Add the instruction to the expression map - //VMC.ExprMap[V] = Result; - return Result; - } - - - BasicBlock *BB = I->getParent(); - std::string Name = I->getName(); if (!Name.empty()) I->setName(""); - Instruction *Res; // Result of conversion - - ValueHandle IHandle(VMC, I); // Prevent I from being removed! - - Constant *Dummy = Constant::getNullValue(Ty); - - switch (I->getOpcode()) { - case Instruction::BitCast: { - assert(VMC.NewCasts.count(ValueHandle(VMC, I)) == 0); - Instruction::CastOps opcode = CastInst::getCastOpcode(I->getOperand(0), - false, Ty, false); - Res = CastInst::create(opcode, I->getOperand(0), Ty, Name); - VMC.NewCasts.insert(ValueHandle(VMC, Res)); - break; - } - - case Instruction::Add: - case Instruction::Sub: - Res = BinaryOperator::create(cast(I)->getOpcode(), - Dummy, Dummy, Name); - VMC.ExprMap[I] = Res; // Add node to expression eagerly - - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), Ty, VMC, TD)); - Res->setOperand(1, ConvertExpressionToType(I->getOperand(1), Ty, VMC, TD)); - break; - - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr: - Res = BinaryOperator::create(cast(I)->getOpcode(), Dummy, - I->getOperand(1), Name); - VMC.ExprMap[I] = Res; - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), Ty, VMC, TD)); - break; - - case Instruction::Load: { - LoadInst *LI = cast(I); - - Res = new LoadInst(Constant::getNullValue(PointerType::get(Ty)), Name); - VMC.ExprMap[I] = Res; - Res->setOperand(0, ConvertExpressionToType(LI->getPointerOperand(), - PointerType::get(Ty), VMC, TD)); - assert(Res->getOperand(0)->getType() == PointerType::get(Ty)); - assert(Ty == Res->getType()); - assert(Res->getType()->isFirstClassType() && "Load of structure or array!"); - break; - } - - case Instruction::PHI: { - PHINode *OldPN = cast(I); - PHINode *NewPN = new PHINode(Ty, Name); - - VMC.ExprMap[I] = NewPN; // Add node to expression eagerly - while (OldPN->getNumOperands()) { - BasicBlock *BB = OldPN->getIncomingBlock(0); - Value *OldVal = OldPN->getIncomingValue(0); - ValueHandle OldValHandle(VMC, OldVal); - OldPN->removeIncomingValue(BB, false); - Value *V = ConvertExpressionToType(OldVal, Ty, VMC, TD); - NewPN->addIncoming(V, BB); - } - Res = NewPN; - break; - } - - case Instruction::GetElementPtr: { - // GetElementPtr's are directly convertible 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(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... - // - std::vector Indices(GEP->idx_begin(), GEP->idx_end()); - const Type *BaseType = GEP->getPointerOperand()->getType(); - const Type *PVTy = cast(Ty)->getElementType(); - Res = 0; - while (!Indices.empty() && - Indices.back() == Constant::getNullValue(Indices.back()->getType())){ - Indices.pop_back(); - if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) { - if (Indices.size() == 0) - // We want to no-op cast this so use BitCast - Res = new BitCastInst(GEP->getPointerOperand(), BaseType); - else - Res = new GetElementPtrInst(GEP->getPointerOperand(), Indices, Name); - break; - } - } - - // Otherwise, it could be that we have something like this: - // getelementptr [[sbyte] *] * %reg115, uint %reg138 ; [sbyte]** - // and want to convert it into something like this: - // getelemenptr [[int] *] * %reg115, uint %reg138 ; [int]** - // - if (Res == 0) { - const PointerType *NewSrcTy = PointerType::get(PVTy); - std::vector Indices(GEP->idx_begin(), GEP->idx_end()); - Res = new GetElementPtrInst(Constant::getNullValue(NewSrcTy), - Indices, Name); - VMC.ExprMap[I] = Res; - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), - NewSrcTy, VMC, TD)); - } - - - assert(Res && "Didn't find match!"); - break; - } - - case Instruction::Call: { - assert(!isa(I->getOperand(0))); - - // If this is a function pointer, we can convert the return type if we can - // convert the source function pointer. - // - const PointerType *PT = cast(I->getOperand(0)->getType()); - const FunctionType *FT = cast(PT->getElementType()); - std::vector ArgTys(FT->param_begin(), FT->param_end()); - const FunctionType *NewTy = - FunctionType::get(Ty, ArgTys, FT->isVarArg()); - const PointerType *NewPTy = PointerType::get(NewTy); - if (Ty == Type::VoidTy) - Name = ""; // Make sure not to name calls that now return void! - - Res = new CallInst(Constant::getNullValue(NewPTy), - std::vector(I->op_begin()+1, I->op_end()), - Name); - if (cast(I)->isTailCall()) - cast(Res)->setTailCall(); - cast(Res)->setCallingConv(cast(I)->getCallingConv()); - VMC.ExprMap[I] = Res; - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0),NewPTy,VMC,TD)); - break; - } - default: - assert(0 && "Expression convertible, but don't know how to convert?"); - return 0; - } - - assert(Res->getType() == Ty && "Didn't convert expr to correct type!"); - - BB->getInstList().insert(I, Res); - - // Add the instruction to the expression map - VMC.ExprMap[I] = Res; - - - //// WTF is this code! FIXME: remove this. - unsigned NumUses = I->getNumUses(); - for (unsigned It = 0; It < NumUses; ) { - unsigned OldSize = NumUses; - Value::use_iterator UI = I->use_begin(); - std::advance(UI, It); - ConvertOperandToType(*UI, I, Res, VMC, TD); - NumUses = I->getNumUses(); - if (NumUses == OldSize) ++It; - } - - DOUT << "ExpIn: " << (void*)I << " " << *I - << "ExpOut: " << (void*)Res << " " << *Res; - - return Res; -} - - - -// ValueConvertibleToType - Return true if it is possible -bool llvm::ValueConvertibleToType(Value *V, const Type *Ty, - ValueTypeCache &ConvertedTypes, - const TargetData &TD) { - ValueTypeCache::iterator I = ConvertedTypes.find(V); - if (I != ConvertedTypes.end()) return I->second == Ty; - ConvertedTypes[V] = Ty; - - // It is safe to convert the specified value to the specified type IFF all of - // the uses of the value can be converted to accept the new typed value. - // - if (V->getType() != Ty) { - for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) - if (!OperandConvertibleToType(*I, V, Ty, ConvertedTypes, TD)) - return false; - } - - return true; -} - -// OperandConvertibleToType - Return true if it is possible to convert operand -// V of User (instruction) U to the specified type. This is true iff it is -// possible to change the specified instruction to accept this. CTMap is a map -// of converted types, so that circular definitions will see the future type of -// the expression, not the static current type. -// -static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, - ValueTypeCache &CTMap, - const TargetData &TD) { - // if (V->getType() == Ty) return true; // Operand already the right type? - - // Expression type must be holdable in a register. - if (!Ty->isFirstClassType()) - return false; - - Instruction *I = dyn_cast(U); - if (I == 0) return false; // We can't convert non-instructions! - - switch (I->getOpcode()) { - case Instruction::BitCast: - assert(I->getOperand(0) == V); - // We can convert the expr if the cast destination type is losslessly - // convertible to the requested type. Also, do not change a cast that - // is a noop cast. For all intents and purposes it should be eliminated. - if (!cast(I)->isLosslessCast() || - I->getType() == I->getOperand(0)->getType()) - return false; - - // We also do not allow conversion of a cast that casts from a ptr to array - // of X to a *X. For example: cast [4 x %List *] * %val to %List * * - // - if (const PointerType *SPT = - dyn_cast(I->getOperand(0)->getType())) - if (const PointerType *DPT = dyn_cast(I->getType())) - if (const ArrayType *AT = dyn_cast(SPT->getElementType())) - if (AT->getElementType() == DPT->getElementType()) - return false; - return true; - - case Instruction::Add: - case Instruction::Sub: { - if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false; - - Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0); - return ValueConvertibleToType(I, Ty, CTMap, TD) && - ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD); - } - case Instruction::ICmp: { - if (cast(I)->getPredicate() == ICmpInst::ICMP_EQ || - cast(I)->getPredicate() == ICmpInst::ICMP_NE) { - Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0); - return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD); - } - return false; - } - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr: - if (I->getOperand(1) == V) return false; // Cannot change shift amount type - if (!Ty->isInteger()) return false; - return ValueConvertibleToType(I, Ty, CTMap, TD); - - case Instruction::Free: - assert(I->getOperand(0) == V); - return isa(Ty); // Free can free any pointer type! - - case Instruction::Load: - // Cannot convert the types of any subscripts... - if (I->getOperand(0) != V) return false; - - if (const PointerType *PT = dyn_cast(Ty)) { - LoadInst *LI = cast(I); - - const Type *LoadedTy = PT->getElementType(); - - // They could be loading the first element of a composite type... - if (const CompositeType *CT = dyn_cast(LoadedTy)) { - unsigned Offset = 0; // No offset, get first leaf. - std::vector Indices; // Discarded... - LoadedTy = getStructOffsetType(CT, Offset, Indices, TD, false); - assert(Offset == 0 && "Offset changed from zero???"); - } - - if (!LoadedTy->isFirstClassType()) - return false; - - if (TD.getTypeSize(LoadedTy) != TD.getTypeSize(LI->getType())) - return false; - - return ValueConvertibleToType(LI, LoadedTy, CTMap, TD); - } - return false; - - case Instruction::Store: { - if (V == I->getOperand(0)) { - ValueTypeCache::iterator CTMI = CTMap.find(I->getOperand(1)); - if (CTMI != CTMap.end()) { // Operand #1 is in the table already? - // If so, check to see if it's Ty*, or, more importantly, if it is a - // pointer to a structure where the first element is a Ty... this code - // is necessary because we might be trying to change the source and - // destination type of the store (they might be related) and the dest - // pointer type might be a pointer to structure. Below we allow pointer - // to structures where the 0th element is compatible with the value, - // now we have to support the symmetrical part of this. - // - const Type *ElTy = cast(CTMI->second)->getElementType(); - - // Already a pointer to what we want? Trivially accept... - if (ElTy == Ty) return true; - - // Tricky case now, if the destination is a pointer to structure, - // obviously the source is not allowed to be a structure (cannot copy - // a whole structure at a time), so the level raiser must be trying to - // store into the first field. Check for this and allow it now: - // - if (isa(ElTy)) { - unsigned Offset = 0; - std::vector Indices; - ElTy = getStructOffsetType(ElTy, Offset, Indices, TD, false); - assert(Offset == 0 && "Offset changed!"); - if (ElTy == 0) // Element at offset zero in struct doesn't exist! - return false; // Can only happen for {}* - - if (ElTy == Ty) // Looks like the 0th element of structure is - return true; // compatible! Accept now! - - // Otherwise we know that we can't work, so just stop trying now. - return false; - } - } - - // Can convert the store if we can convert the pointer operand to match - // the new value type... - return ExpressionConvertibleToType(I->getOperand(1), PointerType::get(Ty), - CTMap, TD); - } else if (const PointerType *PT = dyn_cast(Ty)) { - const Type *ElTy = PT->getElementType(); - assert(V == I->getOperand(1)); - - if (isa(ElTy)) { - // We can change the destination pointer if we can store our first - // argument into the first element of the structure... - // - unsigned Offset = 0; - std::vector Indices; - ElTy = getStructOffsetType(ElTy, Offset, Indices, TD, false); - assert(Offset == 0 && "Offset changed!"); - if (ElTy == 0) // Element at offset zero in struct doesn't exist! - return false; // Can only happen for {}* - } - - // Must move the same amount of data... - if (!ElTy->isSized() || - TD.getTypeSize(ElTy) != TD.getTypeSize(I->getOperand(0)->getType())) - return false; - - // Can convert store if the incoming value is convertible and if the - // result will preserve semantics... - const Type *Op0Ty = I->getOperand(0)->getType(); - if (Op0Ty->isInteger() == ElTy->isInteger() && - Op0Ty->isFloatingPoint() == ElTy->isFloatingPoint()) - return ExpressionConvertibleToType(I->getOperand(0), ElTy, CTMap, TD); - } - return false; - } - - case Instruction::PHI: { - PHINode *PN = cast(I); - // Be conservative if we find a giant PHI node. - if (PN->getNumIncomingValues() > 32) return false; - - for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) - if (!ExpressionConvertibleToType(PN->getIncomingValue(i), Ty, CTMap, TD)) - return false; - return ValueConvertibleToType(PN, Ty, CTMap, TD); - } - - case Instruction::Call: { - User::op_iterator OI = std::find(I->op_begin(), I->op_end(), V); - assert (OI != I->op_end() && "Not using value!"); - unsigned OpNum = OI - I->op_begin(); - - // Are we trying to change the function pointer value to a new type? - if (OpNum == 0) { - const PointerType *PTy = dyn_cast(Ty); - if (PTy == 0) return false; // Can't convert to a non-pointer type... - const FunctionType *FTy = dyn_cast(PTy->getElementType()); - if (FTy == 0) return false; // Can't convert to a non ptr to function... - - // Do not allow converting to a call where all of the operands are ...'s - if (FTy->getNumParams() == 0 && FTy->isVarArg()) - return false; // Do not permit this conversion! - - // Perform sanity checks to make sure that new function type has the - // correct number of arguments... - // - unsigned NumArgs = I->getNumOperands()-1; // Don't include function ptr - - // Cannot convert to a type that requires more fixed arguments than - // the call provides... - // - if (NumArgs < FTy->getNumParams()) return false; - - // Unless this is a vararg function type, we cannot provide more arguments - // than are desired... - // - if (!FTy->isVarArg() && NumArgs > FTy->getNumParams()) - return false; - - // Okay, at this point, we know that the call and the function type match - // number of arguments. Now we see if we can convert the arguments - // themselves. Note that we do not require operands to be convertible, - // we can insert casts if they are convertible but not compatible. The - // reason for this is that we prefer to have resolved functions but casted - // arguments if possible. - // - for (unsigned i = 0, NA = FTy->getNumParams(); i < NA; ++i) - if (FTy->getParamType(i) != I->getOperand(i+1)->getType()) - return false; // Operands must have compatible types! - - // Okay, at this point, we know that all of the arguments can be - // converted. We succeed if we can change the return type if - // necessary... - // - return ValueConvertibleToType(I, FTy->getReturnType(), CTMap, TD); - } - - const PointerType *MPtr = cast(I->getOperand(0)->getType()); - const FunctionType *FTy = cast(MPtr->getElementType()); - if (!FTy->isVarArg()) return false; - - if ((OpNum-1) < FTy->getNumParams()) - return false; // It's not in the varargs section... - - // If we get this far, we know the value is in the varargs section of the - // function! We can convert if we don't reinterpret the value... - // - return isa(Ty) && isa(V->getType()); - } - } - return false; -} - - -void llvm::ConvertValueToNewType(Value *V, Value *NewVal, ValueMapCache &VMC, - const TargetData &TD) { - ValueHandle VH(VMC, V); - - // FIXME: This is horrible! - unsigned NumUses = V->getNumUses(); - for (unsigned It = 0; It < NumUses; ) { - unsigned OldSize = NumUses; - Value::use_iterator UI = V->use_begin(); - std::advance(UI, It); - ConvertOperandToType(*UI, V, NewVal, VMC, TD); - NumUses = V->getNumUses(); - if (NumUses == OldSize) ++It; - } -} - - - -static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, - ValueMapCache &VMC, const TargetData &TD) { - if (isa(U)) return; // Valuehandles don't let go of operands... - - if (VMC.OperandsMapped.count(U)) return; - VMC.OperandsMapped.insert(U); - - ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(U); - if (VMCI != VMC.ExprMap.end()) - return; - - - Instruction *I = cast(U); // Only Instructions convertible - - BasicBlock *BB = I->getParent(); - assert(BB != 0 && "Instruction not embedded in basic block!"); - std::string Name = I->getName(); - I->setName(""); - Instruction *Res = 0; // Result of conversion - - //cerr << endl << endl << "Type:\t" << Ty << "\nInst: " << I - // << "BB Before: " << BB << endl; - - // Prevent I from being removed... - ValueHandle IHandle(VMC, I); - - const Type *NewTy = NewVal->getType(); - Constant *Dummy = (NewTy != Type::VoidTy) ? - Constant::getNullValue(NewTy) : 0; - - switch (I->getOpcode()) { - case Instruction::BitCast: { - Instruction::CastOps opcode = CastInst::getCastOpcode(NewVal, false, - I->getType(), false); - Res = CastInst::create(opcode, NewVal, I->getType(), Name); - break; - } - - case Instruction::Add: - case Instruction::Sub: { - Res = BinaryOperator::create(cast(I)->getOpcode(), - Dummy, Dummy, Name); - VMC.ExprMap[I] = Res; // Add node to expression eagerly - - unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0; - Value *OtherOp = I->getOperand(OtherIdx); - Res->setOperand(!OtherIdx, NewVal); - Value *NewOther = ConvertExpressionToType(OtherOp, NewTy, VMC, TD); - Res->setOperand(OtherIdx, NewOther); - break; - } - case Instruction::ICmp: { - ICmpInst::Predicate pred = cast(I)->getPredicate(); - if (pred == ICmpInst::ICMP_EQ || pred == ICmpInst::ICMP_NE) { - Res = new ICmpInst(pred, Dummy, Dummy, Name); - VMC.ExprMap[I] = Res; // Add node to expression eagerly - unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0; - Value *OtherOp = I->getOperand(OtherIdx); - Res->setOperand(!OtherIdx, NewVal); - Value *NewOther = ConvertExpressionToType(OtherOp, NewTy, VMC, TD); - Res->setOperand(OtherIdx, NewOther); - } - break; - } - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr: - assert(I->getOperand(0) == OldVal); - Res = BinaryOperator::create(cast(I)->getOpcode(), NewVal, - I->getOperand(1), Name); - break; - - case Instruction::Free: // Free can free any pointer type! - assert(I->getOperand(0) == OldVal); - Res = new FreeInst(NewVal); - break; - - - case Instruction::Load: { - assert(I->getOperand(0) == OldVal && isa(NewVal->getType())); - const Type *LoadedTy = - cast(NewVal->getType())->getElementType(); - - Value *Src = NewVal; - - if (const CompositeType *CT = dyn_cast(LoadedTy)) { - std::vector Indices; - Indices.push_back(Constant::getNullValue(Type::Int32Ty)); - - unsigned Offset = 0; // No offset, get first leaf. - LoadedTy = getStructOffsetType(CT, Offset, Indices, TD, false); - assert(LoadedTy->isFirstClassType()); - - if (Indices.size() != 1) { // Do not generate load X, 0 - // Insert the GEP instruction before this load. - Src = new GetElementPtrInst(Src, Indices, Name+".idx", I); - } - } - - Res = new LoadInst(Src, Name); - assert(Res->getType()->isFirstClassType() && "Load of structure or array!"); - break; - } - - case Instruction::Store: { - if (I->getOperand(0) == OldVal) { // Replace the source value - // Check to see if operand #1 has already been converted... - ValueMapCache::ExprMapTy::iterator VMCI = - VMC.ExprMap.find(I->getOperand(1)); - if (VMCI != VMC.ExprMap.end()) { - // Comments describing this stuff are in the OperandConvertibleToType - // switch statement for Store... - // - const Type *ElTy = - cast(VMCI->second->getType())->getElementType(); - - Value *SrcPtr = VMCI->second; - - if (ElTy != NewTy) { - std::vector Indices; - Indices.push_back(Constant::getNullValue(Type::Int32Ty)); - - unsigned Offset = 0; - const Type *Ty = getStructOffsetType(ElTy, Offset, Indices, TD,false); - 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", I); - } - Res = new StoreInst(NewVal, SrcPtr); - - VMC.ExprMap[I] = Res; - } else { - // Otherwise, we haven't converted Operand #1 over yet... - const PointerType *NewPT = PointerType::get(NewTy); - Res = new StoreInst(NewVal, Constant::getNullValue(NewPT)); - VMC.ExprMap[I] = Res; - Res->setOperand(1, ConvertExpressionToType(I->getOperand(1), - NewPT, VMC, TD)); - } - } else { // Replace the source pointer - const Type *ValTy = cast(NewTy)->getElementType(); - - Value *SrcPtr = NewVal; - - if (isa(ValTy)) { - std::vector Indices; - Indices.push_back(Constant::getNullValue(Type::Int32Ty)); - - unsigned Offset = 0; - ValTy = getStructOffsetType(ValTy, Offset, Indices, TD, false); - - assert(Offset == 0 && ValTy); - - // Insert the GEP instruction before this store. - SrcPtr = new GetElementPtrInst(SrcPtr, Indices, - SrcPtr->getName()+".idx", I); - } - - Res = new StoreInst(Constant::getNullValue(ValTy), SrcPtr); - VMC.ExprMap[I] = Res; - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), - ValTy, VMC, TD)); - } - break; - } - - case Instruction::PHI: { - PHINode *OldPN = cast(I); - PHINode *NewPN = new PHINode(NewTy, Name); - VMC.ExprMap[I] = NewPN; - - while (OldPN->getNumOperands()) { - BasicBlock *BB = OldPN->getIncomingBlock(0); - Value *OldVal = OldPN->getIncomingValue(0); - ValueHandle OldValHandle(VMC, OldVal); - OldPN->removeIncomingValue(BB, false); - Value *V = ConvertExpressionToType(OldVal, NewTy, VMC, TD); - NewPN->addIncoming(V, BB); - } - Res = NewPN; - break; - } - - case Instruction::Call: { - Value *Meth = I->getOperand(0); - std::vector Params(I->op_begin()+1, I->op_end()); - - if (Meth == OldVal) { // Changing the function pointer? - const PointerType *NewPTy = cast(NewVal->getType()); - const FunctionType *NewTy = cast(NewPTy->getElementType()); - - if (NewTy->getReturnType() == Type::VoidTy) - Name = ""; // Make sure not to name a void call! - - // Get an iterator to the call instruction so that we can insert casts for - // operands if need be. Note that we do not require operands to be - // convertible, we can insert casts if they are convertible but not - // compatible. The reason for this is that we prefer to have resolved - // functions but casted arguments if possible. - // - BasicBlock::iterator It = I; - - // Convert over all of the call operands to their new types... but only - // convert over the part that is not in the vararg section of the call. - // - for (unsigned i = 0; i != NewTy->getNumParams(); ++i) - if (Params[i]->getType() != NewTy->getParamType(i)) { - // Create a cast to convert it to the right type, we know that this - // is a no-op cast... - // - Params[i] = new BitCastInst(Params[i], NewTy->getParamType(i), - "callarg.cast." + - Params[i]->getName(), It); - } - Meth = NewVal; // Update call destination to new value - - } else { // Changing an argument, must be in vararg area - std::vector::iterator OI = - std::find(Params.begin(), Params.end(), OldVal); - assert (OI != Params.end() && "Not using value!"); - - *OI = NewVal; - } - - Res = new CallInst(Meth, Params, Name); - if (cast(I)->isTailCall()) - cast(Res)->setTailCall(); - cast(Res)->setCallingConv(cast(I)->getCallingConv()); - break; - } - default: - assert(0 && "Expression convertible, but don't know how to convert?"); - return; - } - - assert(Res != 0 && "We didn't get a result conversion?"); - - // If the instruction was newly created, insert it into the instruction - // stream. - // - BasicBlock::iterator It = I; - assert(It != BB->end() && "Instruction not in own basic block??"); - BB->getInstList().insert(It, Res); // Keep It pointing to old instruction - - DOUT << "COT CREATED: " << (void*)Res << " " << *Res - << "In: " << (void*)I << " " << *I << "Out: " << (void*)Res - << " " << *Res; - - // Add the instruction to the expression map - VMC.ExprMap[I] = Res; - - if (I->getType() != Res->getType()) - ConvertValueToNewType(I, Res, VMC, TD); - else { - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ) - if (isa(*UI)) { - ++UI; - } else { - Use &U = UI.getUse(); - ++UI; // Do not invalidate UI. - U.set(Res); - } - } -} - - -ValueHandle::ValueHandle(ValueMapCache &VMC, Value *V) - : Instruction(Type::VoidTy, UserOp1, &Op, 1, ""), Op(V, this), Cache(VMC) { - //DOUT << "VH AQUIRING: " << (void*)V << " " << V; -} - -ValueHandle::ValueHandle(const ValueHandle &VH) - : Instruction(Type::VoidTy, UserOp1, &Op, 1, ""), - Op(VH.Op, this), Cache(VH.Cache) { - //DOUT << "VH AQUIRING: " << (void*)V << " " << V; -} - -static void RecursiveDelete(ValueMapCache &Cache, Instruction *I) { - if (!I || !I->use_empty()) return; - - assert(I->getParent() && "Inst not in basic block!"); - - //DOUT << "VH DELETING: " << (void*)I << " " << I; - - for (User::op_iterator OI = I->op_begin(), OE = I->op_end(); - OI != OE; ++OI) - if (Instruction *U = dyn_cast(OI)) { - *OI = 0; - RecursiveDelete(Cache, U); - } - - I->getParent()->getInstList().remove(I); - - Cache.OperandsMapped.erase(I); - Cache.ExprMap.erase(I); - delete I; -} - -ValueHandle::~ValueHandle() { - if (Op->hasOneUse()) { - Value *V = Op; - Op.set(0); // Drop use! - - // Now we just need to remove the old instruction so we don't get infinite - // loops. Note that we cannot use DCE because DCE won't remove a store - // instruction, for example. - // - RecursiveDelete(Cache, dyn_cast(V)); - } else { - //DOUT << "VH RELEASING: " << (void*)Operands[0].get() << " " - // << Operands[0]->getNumUses() << " " << Operands[0]; - } -} diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp deleted file mode 100644 index 4ebf25b49c..0000000000 --- a/lib/Transforms/LevelRaise.cpp +++ /dev/null @@ -1,452 +0,0 @@ -//===- LevelRaise.cpp - Code to change LLVM to higher level ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the 'raising' part of the LevelChange API. This is -// useful because, in general, it makes the LLVM code terser and easier to -// analyze. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "raise" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/Local.h" -#include "TransformInternals.h" -#include "llvm/Instructions.h" -#include "llvm/Pass.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/STLExtras.h" -#include -using namespace llvm; - -// StartInst - This enables the -raise-start-inst=foo option to cause the level -// raising pass to start at instruction "foo", which is immensely useful for -// debugging! -// -static cl::opt -StartInst("raise-start-inst", cl::Hidden, cl::value_desc("inst name"), - cl::desc("Start raise pass at the instruction with the specified name")); - -STATISTIC(NumLoadStorePeepholes, "Number of load/store peepholes"); - -STATISTIC(NumGEPInstFormed, "Number of other getelementptr's formed"); - -STATISTIC(NumExprTreesConv, "Number of expression trees converted"); - -STATISTIC(NumCastOfCast, "Number of cast-of-self removed"); - -STATISTIC(NumDCEorCP, "Number of insts DCEd or constprop'd"); - -STATISTIC(NumVarargCallChanges, "Number of vararg call peepholes"); - -#define PRINT_PEEPHOLE(ID, NUM, I) \ - DOUT << "Inst P/H " << ID << "[" << NUM << "] " << I - -#define PRINT_PEEPHOLE1(ID, I1) do { PRINT_PEEPHOLE(ID, 0, I1); } while (0) -#define PRINT_PEEPHOLE2(ID, I1, I2) \ - do { PRINT_PEEPHOLE(ID, 0, I1); PRINT_PEEPHOLE(ID, 1, I2); } while (0) -#define PRINT_PEEPHOLE3(ID, I1, I2, I3) \ - do { PRINT_PEEPHOLE(ID, 0, I1); PRINT_PEEPHOLE(ID, 1, I2); \ - PRINT_PEEPHOLE(ID, 2, I3); } while (0) -#define PRINT_PEEPHOLE4(ID, I1, I2, I3, I4) \ - do { PRINT_PEEPHOLE(ID, 0, I1); PRINT_PEEPHOLE(ID, 1, I2); \ - PRINT_PEEPHOLE(ID, 2, I3); PRINT_PEEPHOLE(ID, 3, I4); } while (0) - -namespace { - struct RPR : public FunctionPass { - virtual bool runOnFunction(Function &F); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); - AU.addRequired(); - } - - private: - bool DoRaisePass(Function &F); - bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI); - }; - - RegisterPass X("raise", "Raise Pointer References"); -} - - -FunctionPass *llvm::createRaisePointerReferencesPass() { - return new RPR(); -} - -bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { - Instruction *I = BI; - const TargetData &TD = getAnalysis(); - - if (CastInst *CI = dyn_cast(I)) { - Value *Src = CI->getOperand(0); - const Type *DestTy = CI->getType(); - - // Peephole optimize the following instruction: - // %V2 = cast %V to - // - // Into: - // - if (DestTy == Src->getType()) { // Check for a cast to same type as src!! - PRINT_PEEPHOLE1("cast-of-self-ty", *CI); - CI->replaceAllUsesWith(Src); - if (!Src->hasName() && CI->hasName()) { - std::string Name = CI->getName(); - CI->setName(""); - Src->setName(Name); - } - - // DCE the instruction now, to avoid having the iterative version of DCE - // have to worry about it. - // - BI = BB->getInstList().erase(BI); - - ++NumCastOfCast; - return true; - } - - // 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 (CI->isLosslessCast()) { - ValueTypeCache ConvertedTypes; - - // Check to see if we can convert the source of the cast to match the - // destination type of the cast... - // - ConvertedTypes[CI] = CI->getType(); // Make sure the cast doesn't change - if (ExpressionConvertibleToType(Src, DestTy, ConvertedTypes, TD)) { - PRINT_PEEPHOLE3("CAST-SRC-EXPR-CONV:in ", *Src, *CI, *BB->getParent()); - - DOUT << "\nCONVERTING SRC EXPR TYPE:\n"; - { // ValueMap must be destroyed before function verified! - ValueMapCache ValueMap; - Value *E = ConvertExpressionToType(Src, DestTy, ValueMap, TD); - - if (Constant *CPV = dyn_cast(E)) - CI->replaceAllUsesWith(CPV); - - PRINT_PEEPHOLE1("CAST-SRC-EXPR-CONV:out", *E); - DOUT << "DONE CONVERTING SRC EXPR TYPE: \n" - << *BB->getParent(); - } - - BI = BB->begin(); // Rescan basic block. BI might be invalidated. - ++NumExprTreesConv; - return true; - } - - // Check to see if we can convert the users of the cast value to match the - // source type of the cast... - // - ConvertedTypes.clear(); - // Make sure the source doesn't change type - ConvertedTypes[Src] = Src->getType(); - if (ValueConvertibleToType(CI, Src->getType(), ConvertedTypes, TD)) { - //PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", *Src, *CI, - // *BB->getParent()); - - DOUT << "\nCONVERTING EXPR TYPE:\n"; - { // ValueMap must be destroyed before function verified! - ValueMapCache ValueMap; - ConvertValueToNewType(CI, Src, ValueMap, TD); // This will delete CI! - } - - PRINT_PEEPHOLE1("CAST-DEST-EXPR-CONV:out", *Src); - DOUT << "DONE CONVERTING EXPR TYPE: \n\n" << *BB->getParent(); - - BI = BB->begin(); // Rescan basic block. BI might be invalidated. - ++NumExprTreesConv; - return true; - } - } - - // Check to see if we are casting from a structure pointer to a pointer to - // the first element of the structure... to avoid munching other peepholes, - // we only let this happen if there are no add uses of the cast. - // - // Peephole optimize the following instructions: - // %t1 = cast {<...>} * %StructPtr to * - // - // Into: %t2 = getelementptr {<...>} * %StructPtr, <0, 0, 0, ...> - // %t1 = cast * %t1 to * - // - if (const CompositeType *CTy = getPointedToComposite(Src->getType())) - if (const PointerType *DestPTy = dyn_cast(DestTy)) { - - // Loop over uses of the cast, checking for add instructions. If an add - // exists, this is probably a part of a more complex GEP, so we don't - // want to mess around with the cast. - // - bool HasAddUse = false; - for (Value::use_iterator I = CI->use_begin(), E = CI->use_end(); - I != E; ++I) - if (isa(*I) && - cast(*I)->getOpcode() == Instruction::Add) { - HasAddUse = true; break; - } - - // If it doesn't have an add use, check to see if the dest type is - // losslessly convertible to one of the types in the start of the struct - // type. - // - if (!HasAddUse) { - const Type *DestPointedTy = DestPTy->getElementType(); - unsigned Depth = 1; - const CompositeType *CurCTy = CTy; - const Type *ElTy = 0; - - // Build the index vector, full of all zeros - std::vector Indices; - - Indices.push_back(Constant::getNullValue(Type::Int32Ty)); - while (CurCTy && !isa(CurCTy)) { - if (const StructType *CurSTy = dyn_cast(CurCTy)) { - // Check for a zero element struct type... if we have one, bail. - if (CurSTy->getNumElements() == 0) break; - - // Grab the first element of the struct type, which must lie at - // offset zero in the struct. - // - ElTy = CurSTy->getElementType(0); - } else { - ElTy = cast(CurCTy)->getElementType(); - } - - // Insert a zero to index through this type... - Indices.push_back(Constant::getNullValue(Type::Int32Ty)); - - // Did we find what we're looking for? - if (ElTy->canLosslesslyBitCastTo(DestPointedTy)) break; - - // Nope, go a level deeper. - ++Depth; - CurCTy = dyn_cast(ElTy); - ElTy = 0; - } - - // Did we find what we were looking for? If so, do the transformation - 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, - Name, BI); - - // Make the old cast instruction reference the new GEP instead of - // the old src value. - if (CI->getOperand(0)->getType() == GEP->getType()) { - // If the source types are the same we can safely replace the - // first operand of the CastInst because the opcode won't - // change as a result. - CI->setOperand(0, GEP); - } else { - // The existing and new operand 0 types are different so we must - // replace CI with a new CastInst so that we are assured to - // get the correct cast opcode. - CastInst *NewCI = new BitCastInst(GEP, CI->getType(), - CI->getName(), CI); - CI->replaceAllUsesWith(NewCI); - CI->eraseFromParent(); - CI = NewCI; - BI = NewCI; // Don't let the iterator invalidate - } - - PRINT_PEEPHOLE2("cast-for-first:out", *GEP, *CI); - ++NumGEPInstFormed; - return true; - } - } - } - - } else if (StoreInst *SI = dyn_cast(I)) { - Value *Val = SI->getOperand(0); - Value *Pointer = SI->getPointerOperand(); - - // Peephole optimize the following instructions: - // %t = cast * %P to * ;; If T1 is losslessly castable to T2 - // store %V, * %t - // - // Into: - // %t = cast %V to - // store %t2, * %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(Pointer)) - if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType - if (const PointerType *CSPT = dyn_cast(CastSrc->getType())) - // convertible types? - if (Val->getType()->canLosslesslyBitCastTo(CSPT->getElementType())) - { - 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 = CastInst::create(Instruction::BitCast, Val, - CSPT->getElementType(), Name, BI); - - // Replace the old store with a new one! - ReplaceInstWithInst(BB->getInstList(), BI, - SI = new StoreInst(NCI, CastSrc)); - PRINT_PEEPHOLE3("st-src-cast:out", *NCI, *CastSrc, *SI); - ++NumLoadStorePeepholes; - return true; - } - - } else if (LoadInst *LI = dyn_cast(I)) { - Value *Pointer = LI->getOperand(0); - const Type *PtrElType = - cast(Pointer->getType())->getElementType(); - - // Peephole optimize the following instructions: - // %Val = cast * to * ;; If T1 is losslessly convertible to T2 - // %t = load * %P - // - // Into: - // %t = load * %P - // %Val = cast to - // - // 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(Pointer)) - if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType - if (const PointerType *CSPT = dyn_cast(CastSrc->getType())) - // convertible types? - if (PtrElType->canLosslesslyBitCastTo(CSPT->getElementType())) { - 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(), BI); - - // Insert the new T cast instruction... stealing old T's name - CastInst *NCI = - CastInst::create(Instruction::BitCast, NewLI, LI->getType(), - CI->getName()); - - // Replace the old store with a new one! - ReplaceInstWithInst(BB->getInstList(), BI, NCI); - PRINT_PEEPHOLE3("load-src-cast:out", *NCI, *CastSrc, *NewLI); - ++NumLoadStorePeepholes; - return true; - } - - } else if (CallInst *CI = dyn_cast(I)) { - // If we have a call with all varargs arguments, convert the call to use the - // actual argument types present... - // - const PointerType *PTy = cast(CI->getCalledValue()->getType()); - const FunctionType *FTy = cast(PTy->getElementType()); - - // Is the call to a vararg variable with no real parameters? - if (FTy->isVarArg() && FTy->getNumParams() == 0 && - !CI->getCalledFunction()) { - // If so, insert a new cast instruction, casting it to a function type - // that matches the current arguments... - // - std::vector Params; // Parameter types... - for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) - Params.push_back(CI->getOperand(i)->getType()); - - FunctionType *NewFT = FunctionType::get(FTy->getReturnType(), - Params, false); - PointerType *NewPFunTy = PointerType::get(NewFT); - - // Create a new cast, inserting it right before the function call... - Value *NewCast; - if (Constant *CS = dyn_cast(CI->getCalledValue())) - NewCast = ConstantExpr::getBitCast(CS, NewPFunTy); - else - NewCast = CastInst::create(Instruction::BitCast, CI->getCalledValue(), - NewPFunTy, - CI->getCalledValue()->getName()+"_c", CI); - - // Create a new call instruction... - CallInst *NewCall = new CallInst(NewCast, - std::vector(CI->op_begin()+1, CI->op_end())); - if (CI->isTailCall()) NewCall->setTailCall(); - NewCall->setCallingConv(CI->getCallingConv()); - ++BI; - ReplaceInstWithInst(CI, NewCall); - - ++NumVarargCallChanges; - return true; - } - - } - - return false; -} - -bool RPR::DoRaisePass(Function &F) { - bool Changed = false; - for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) - for (BasicBlock::iterator BI = BB->begin(); BI != BB->end();) { - DOUT << "LevelRaising: " << *BI; - if (dceInstruction(BI) || doConstantPropagation(BI)) { - Changed = true; - ++NumDCEorCP; - DOUT << "***\t\t^^-- Dead code eliminated!\n"; - } else if (PeepholeOptimize(BB, BI)) { - Changed = true; - } else { - ++BI; - } - } - - return Changed; -} - - -// runOnFunction - Raise a function representation to a higher level. -bool RPR::runOnFunction(Function &F) { - DOUT << "\n\n\nStarting to work on Function '" << F.getName() << "'\n"; - - // Insert casts for all incoming pointer pointer values that are treated as - // arrays... - // - bool Changed = false, LocalChange; - - // If the StartInst option was specified, then Peephole optimize that - // instruction first if it occurs in this function. - // - if (!StartInst.empty()) { - for (Function::iterator BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) - for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) - if (BI->getName() == StartInst) { - bool SavedDebug = DebugFlag; // Save the DEBUG() controlling flag. - DebugFlag = true; // Turn on DEBUG's - Changed |= PeepholeOptimize(BB, BI); - DebugFlag = SavedDebug; // Restore DebugFlag to previous state - } - } - - do { - DOUT << "Looping: \n" << F; - - // Iterate over the function, refining it, until it converges on a stable - // state - LocalChange = false; - while (DoRaisePass(F)) LocalChange = true; - Changed |= LocalChange; - - } while (LocalChange); - - return Changed; -} - diff --git a/lib/Transforms/Makefile b/lib/Transforms/Makefile index c63bb7f1ef..454c4760e4 100644 --- a/lib/Transforms/Makefile +++ b/lib/Transforms/Makefile @@ -9,8 +9,6 @@ LEVEL = ../.. PARALLEL_DIRS = Utils Instrumentation Scalar IPO -LIBRARYNAME = LLVMTransforms -BUILD_ARCHIVE = 1 include $(LEVEL)/Makefile.common diff --git a/lib/Transforms/TransformInternals.cpp b/lib/Transforms/TransformInternals.cpp deleted file mode 100644 index a4b3609942..0000000000 --- a/lib/Transforms/TransformInternals.cpp +++ /dev/null @@ -1,92 +0,0 @@ -//===- TransformInternals.cpp - Implement shared functions for transforms -===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines shared functions used by the different components of the -// Transforms library. -// -//===----------------------------------------------------------------------===// - -#include "TransformInternals.h" -#include "llvm/Type.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -using namespace llvm; - -static const Type *getStructOffsetStep(const StructType *STy, uint64_t &Offset, - std::vector &Indices, - const TargetData &TD) { - assert(Offset < TD.getTypeSize(STy) && "Offset not in composite!"); - const StructLayout *SL = TD.getStructLayout(STy); - - // This loop terminates always on a 0 <= i < MemberOffsets.size() - unsigned i; - for (i = 0; i < SL->MemberOffsets.size()-1; ++i) - if (Offset >= SL->MemberOffsets[i] && Offset < SL->MemberOffsets[i+1]) - break; - - assert(Offset >= SL->MemberOffsets[i] && - (i == SL->MemberOffsets.size()-1 || Offset < SL->MemberOffsets[i+1])); - - // Make sure to save the current index... - Indices.push_back(ConstantInt::get(Type::Int32Ty, i)); - Offset = SL->MemberOffsets[i]; - return STy->getContainedType(i); -} - - -// getStructOffsetType - Return a vector of offsets that are to be used to index -// into the specified struct type to get as close as possible to index as we -// can. Note that it is possible that we cannot get exactly to Offset, in which -// case we update offset to be the offset we actually obtained. The resultant -// leaf type is returned. -// -// If StopEarly is set to true (the default), the first object with the -// specified type is returned, even if it is a struct type itself. In this -// case, this routine will not drill down to the leaf type. Set StopEarly to -// false if you want a leaf -// -const Type *llvm::getStructOffsetType(const Type *Ty, unsigned &Offset, - std::vector &Indices, - const TargetData &TD, bool StopEarly) { - if (Offset == 0 && StopEarly && !Indices.empty()) - return Ty; // Return the leaf type - - uint64_t ThisOffset; - const Type *NextType; - if (const StructType *STy = dyn_cast(Ty)) { - if (STy->getNumElements()) { - Offset = 0; - return STy; - } - - ThisOffset = Offset; - NextType = getStructOffsetStep(STy, ThisOffset, Indices, TD); - } else if (const ArrayType *ATy = dyn_cast(Ty)) { - assert(Offset == 0 || Offset < TD.getTypeSize(ATy) && - "Offset not in composite!"); - - NextType = ATy->getElementType(); - unsigned ChildSize = (unsigned)TD.getTypeSize(NextType); - if (ConstantInt::isValueValidForType(Type::Int32Ty, - uint64_t(Offset/ChildSize))) - Indices.push_back(ConstantInt::get(Type::Int32Ty, Offset/ChildSize)); - else - Indices.push_back(ConstantInt::get(Type::Int64Ty, Offset/ChildSize)); - ThisOffset = (Offset/ChildSize)*ChildSize; - } else { - Offset = 0; // Return the offset that we were able to achieve - return Ty; // Return the leaf type - } - - unsigned SubOffs = unsigned(Offset - ThisOffset); - const Type *LeafTy = getStructOffsetType(NextType, SubOffs, - Indices, TD, StopEarly); - Offset = unsigned(ThisOffset + SubOffs); - return LeafTy; -} diff --git a/test/Transforms/LevelRaise/.cvsignore b/test/Transforms/LevelRaise/.cvsignore deleted file mode 100644 index 7f2443f2f3..0000000000 --- a/test/Transforms/LevelRaise/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Output -*.log -*.sum diff --git a/test/Transforms/LevelRaise/2002-02-14-BadAssertion.ll b/test/Transforms/LevelRaise/2002-02-14-BadAssertion.ll deleted file mode 100644 index 546b6544f8..0000000000 --- a/test/Transforms/LevelRaise/2002-02-14-BadAssertion.ll +++ /dev/null @@ -1,19 +0,0 @@ -; An invalid assertion killed the level raiser. Fixed. -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise - -implementation - -declare int "connect_left"() - -int "do_merge"() -begin - %reg108 = call int %connect_left( ) - %cast1002 = cast ulong 8 to sbyte * - %reg108-idxcast = cast int %reg108 to long - %reg1000 = getelementptr sbyte * %cast1002, long %reg108-idxcast - %cast1003 = cast sbyte * %reg1000 to sbyte * * - %reg112 = load sbyte * * %cast1003 - %cast111 = cast sbyte * %reg112 to int - ret int %cast111 -end diff --git a/test/Transforms/LevelRaise/2002-03-11-Calls.ll b/test/Transforms/LevelRaise/2002-03-11-Calls.ll deleted file mode 100644 index 3e8a58fc36..0000000000 --- a/test/Transforms/LevelRaise/2002-03-11-Calls.ll +++ /dev/null @@ -1,15 +0,0 @@ -; Fixed a problem where level raise would try to forward substitute a cast of a -; method pointer type into a call. In doing so, it would have to change the -; types of the arguments to the call, but broke doing so. -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise - -implementation - - -void "test"(void (int*) *%Fn, long* %Arg) -begin - %Fn2 = cast void (int*) *%Fn to void(long*) * - call void %Fn2(long *%Arg) - ret void -end diff --git a/test/Transforms/LevelRaise/2002-03-14-ConvertableToGEPHang.ll b/test/Transforms/LevelRaise/2002-03-14-ConvertableToGEPHang.ll deleted file mode 100644 index 895d5ae110..0000000000 --- a/test/Transforms/LevelRaise/2002-03-14-ConvertableToGEPHang.ll +++ /dev/null @@ -1,24 +0,0 @@ -; This testcase found a bug in ConvertableToGEP that could cause an infinite loop -; Note that this code is actually miscompiled from the input source, but despite -; that, level raise should not hang! -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise - - %Disjunct = type { \2 *, short, sbyte, sbyte *, { short, short, sbyte, sbyte, \2, sbyte * } *, { short, short, sbyte, sbyte, \2, sbyte * } * } -%chosen_disjuncts = uninitialized global %Disjunct * * ; <%Disjunct * * *> [#uses=1] -implementation - -void "build_image_array"() -begin -bb0: ;[#uses=0] - %reg109 = getelementptr %Disjunct * * * %chosen_disjuncts, long 7 ; <%Disjunct * * *> [#uses=1] - %reg108 = load %Disjunct * * * %reg109 ; <%Disjunct * *> [#uses=1] - %reg1000 = getelementptr %Disjunct * * %reg108, long 3 ; <%Disjunct * *> [#uses=1] - %cast1007 = cast %Disjunct * * %reg1000 to sbyte * * ; [#uses=1] - %reg110 = load sbyte * * %cast1007 ; [#uses=1] - %cast1008 = cast ulong 4 to sbyte * ; [#uses=1] - %A = cast sbyte * %reg110 to ulong - %B = cast sbyte * %cast1008 to ulong - %reg1001 = add ulong %A, %B ; [#uses=0] - ret void -end diff --git a/test/Transforms/LevelRaise/2002-03-20-Crash.ll b/test/Transforms/LevelRaise/2002-03-20-Crash.ll deleted file mode 100644 index 35f4c8df60..0000000000 --- a/test/Transforms/LevelRaise/2002-03-20-Crash.ll +++ /dev/null @@ -1,20 +0,0 @@ -; Level raise is making an incorrect transformation, which causes incorrect -; bytecode to be generated. -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis -; - - %Village = type { [4 x \3 *], \2 *, { \2 *, { int, int, int, \5 * } *, \2 * }, { int, int, int, { \2 *, { int, int, int, \6 * } *, \2 * }, { \2 *, { int, int, int, \6 * } *, \2 * }, { \2 *, { int, int, int, \6 * } *, \2 * }, { \2 *, { int, int, int, \6 * } *, \2 * } }, int, int } -implementation - -%Village *"get_results"(%Village * %village) -begin -bb0: ;[#uses=1] - %cast121 = cast int 24 to ulong ; <%Village *> [#uses=1] - %A = cast %Village* %village to ulong - %reg123 = add ulong %A, %cast121 ; <%Village *> [#uses=1] - %reg123 = cast ulong %reg123 to %Village* - %idx = getelementptr %Village * %reg123, long 0, uint 0, long 0 ; <%Village *> [#uses=1] - %reg118 = load %Village** %idx - ret %Village *%reg118 -end diff --git a/test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll b/test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll deleted file mode 100644 index 182575f2cf..0000000000 --- a/test/Transforms/LevelRaise/2002-03-21-MissedRaise.ll +++ /dev/null @@ -1,24 +0,0 @@ -; This example should be raised to return a Hash directly without casting. -; LevelRaise should eliminate all cast instructions from this testcase. -; -; XFAIL: * -; RUN: llvm-upgrade < %s && -; RUN: llvm-upgrade < %s | llvm-as > /dev/null && -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | notcast - - %Hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } * - %hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } - %hash_el = type { uint, sbyte *, \2 } * -implementation - -%Hash "MakeHash"(int %size, int (uint) * %map) -begin - %reg112 = malloc sbyte, uint 24 ; [#uses=5] - %reg115 = malloc sbyte, uint 96 ; [#uses=1] - %cast237 = bitcast sbyte * %reg112 to sbyte * * ; [#uses=1] - store sbyte * %reg115, sbyte * * %cast237 - - %cast246 = bitcast sbyte * %reg112 to %Hash ; <%Hash> [#uses=1] - ret %Hash %cast246 -end - diff --git a/test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll b/test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll deleted file mode 100644 index e3b533c282..0000000000 --- a/test/Transforms/LevelRaise/2002-03-21-MissedRaise2.ll +++ /dev/null @@ -1,29 +0,0 @@ -; Problem that occured because of obsolete code that only allowed malloc -; instructions to change type if they were 'array' allocations. This -; prevented reg115 from being able to change. -; -; XFAIL: * -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep bitcast - - %Hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } * - %HashEntry = type { uint, sbyte *, \2 } * - %hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } - %hash_entry = type { uint, sbyte *, \2 * } -implementation - -%Hash "MakeHash"(int %size, int (uint) * %map) -begin -bb1: ;[#uses=0] - %reg112 = malloc sbyte * *, uint 3 ; [#uses=4] - %reg115 = malloc sbyte *, uint 1 ; [#uses=1] - store sbyte * * %reg115, sbyte * * * %reg112 - %reg121 = load sbyte * * * %reg112 ; [#uses=1] - %size-idxcast1 = cast int %size to long ; [#uses=1] - %reg1221 = getelementptr sbyte * * %reg121, long %size-idxcast1 ; [#uses=1] - store sbyte * null, sbyte * * %reg1221 - %reg232 = getelementptr sbyte * * * %reg112, long 1 ; [#uses=1] - %cast243 = cast int (uint) * %map to sbyte * * ; [#uses=1] - store sbyte * * %cast243, sbyte * * * %reg232 - %cast246 = cast sbyte * * * %reg112 to %Hash ; <%Hash> [#uses=1] - ret %Hash %cast246 -end diff --git a/test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll b/test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll deleted file mode 100644 index 310f34fb81..0000000000 --- a/test/Transforms/LevelRaise/2002-03-21-MissedRaise3.ll +++ /dev/null @@ -1,19 +0,0 @@ -; XFAIL: * -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep bitcast - - %Hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } * - %HashEntry = type { uint, sbyte *, \2 } * - %hash = type { { uint, sbyte *, \2 } * *, int (uint) *, int } - %hash_entry = type { uint, sbyte *, \2 * } -implementation - -%Hash "MakeHash"(int %size, int (uint) * %map) { - %reg112 = malloc sbyte * *, uint 3 ; [#uses=5] - %reg107-uint = cast int %size to uint ; [#uses=1] - %reg115 = malloc sbyte *, uint %reg107-uint ; [#uses=1] - store sbyte * * %reg115, sbyte * * * %reg112 - - %cast246 = cast sbyte * * * %reg112 to %Hash ; <%Hash> [#uses=1] - ret %Hash %cast246 -} - diff --git a/test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll b/test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll deleted file mode 100644 index 3fa7320a20..0000000000 --- a/test/Transforms/LevelRaise/2002-04-16-MissedRaise.ll +++ /dev/null @@ -1,22 +0,0 @@ -; XFAIL: * -; this testcase is distilled from this C source: -; int *foo(unsigned N, unsigned M) { -; unsigned i = (N+1)*sizeof(int); -; unsigned j = (M+1)*sizeof(int); -; return (int*)malloc(i+j); -; } - -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep bitcast - -implementation - -int* %test(uint %N, uint %M) { - %reg111 = shl uint %N, ubyte 2 ; [#uses=1] - %reg109 = add uint %reg111, 4 ; [#uses=1] - %reg114 = shl uint %M, ubyte 2 ; [#uses=1] - %reg112 = add uint %reg114, 4 ; [#uses=1] - %reg116 = add uint %reg109, %reg112 ; [#uses=1] - %reg117 = malloc sbyte, uint %reg116 ; [#uses=1] - %cast221 = cast sbyte* %reg117 to int* ; [#uses=1] - ret int* %cast221 -} diff --git a/test/Transforms/LevelRaise/2002-05-02-BadCastElimination.ll b/test/Transforms/LevelRaise/2002-05-02-BadCastElimination.ll deleted file mode 100644 index 444d9d4236..0000000000 --- a/test/Transforms/LevelRaise/2002-05-02-BadCastElimination.ll +++ /dev/null @@ -1,24 +0,0 @@ -; This test contains two cast instructions that cannot be eliminated. If the -; input of the "test" function is negative, it should be correctly converted -; to a 32 bit version of the number with all upper 16 bits clear (ushort->uint -; involves no sign extension). Optimizing this to a single cast is invalid! -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise -q | lli -; -implementation - -uint "test"(short %argc) -begin - %cast223 = cast short %argc to ushort ; [#uses=1] - %cast114 = cast ushort %cast223 to uint ; [#uses=1] - ret uint %cast114 -end - -int "main"() -begin - %Ret = call uint %test(short -1) - %test = cast uint %Ret to int - %Res = seteq int %test, -1 ; If it returns -1 as int, it's a failure - %Res = cast bool %Res to int - ret int %Res -end diff --git a/test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll b/test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll deleted file mode 100644 index 7335af090d..0000000000 --- a/test/Transforms/LevelRaise/2002-05-02-MissedRaise.ll +++ /dev/null @@ -1,20 +0,0 @@ -; This testcase is not level raised properly... -; XFAIL: * -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep bitcast - - %List = type { int, %List* } - -implementation - -%List* "createList"(uint %Depth) -begin - %reg110 = malloc uint, uint 4 - store uint %Depth, uint* %reg110 - %reg113 = call %List* %createList( uint %Depth ) - %reg217 = getelementptr uint* %reg110, long 2 - %cast221 = cast uint* %reg217 to %List** - store %List* %reg113, %List** %cast221 - %cast222 = cast uint* %reg110 to %List* - ret %List* %cast222 -end - diff --git a/test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll b/test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll deleted file mode 100644 index 640415408d..0000000000 --- a/test/Transforms/LevelRaise/2002-05-10-LoadPeephole.ll +++ /dev/null @@ -1,10 +0,0 @@ -; This testcase should have the cast propogated through the load -; just like a store does... -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep 'bitcast uint \*' - -int "test"(uint * %Ptr) { - %P2 = cast uint *%Ptr to int * - %Val = load int * %P2 - ret int %Val -} diff --git a/test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll b/test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll deleted file mode 100644 index cbb77870e3..0000000000 --- a/test/Transforms/LevelRaise/2002-05-23-MissedRaise.ll +++ /dev/null @@ -1,20 +0,0 @@ -; XFAIL: * -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep bitcast - -%FILE = type { int, ubyte*, ubyte*, ubyte, ubyte, uint, uint, uint } - -uint %addfile(%FILE* %f) { - %cast255 = cast %FILE* %f to sbyte* - - ; Addreses a ubyte member in memory... - %reg2421 = getelementptr sbyte* %cast255, long 24 - - ; Loads the ubyte - %reg130 = load sbyte* %reg2421 - - ; Error, cast cannot convert the source operand to ubyte because then - ; the sign extension would not be performed. Need to insert a cast. - ; - %cast250 = cast sbyte %reg130 to uint ; This is a sign extension instruction - ret uint %cast250 -} diff --git a/test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll b/test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll deleted file mode 100644 index 456b09fb6a..0000000000 --- a/test/Transforms/LevelRaise/2002-07-16-MissedRaise.ll +++ /dev/null @@ -1,22 +0,0 @@ -; This case fails raise because the store requires that it's argument is of a -; particular type, but the gep is unable to propogate types backwards through -; it, because it doesn't know what type to ask it's operand to be. -; -; This could be fixed by making all stores add themselves to a list, and check -; their arguments are consistent AFTER all other values are propogated. -; XFAIL: * -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | notcast - - %Tree = type %struct.tree* - %struct.tree = type { int, double, double, %Tree, %Tree, %Tree, %Tree } - -void %reverse(%Tree %t) { -bb0: ;[#uses=0] - %cast219 = cast %Tree %t to sbyte*** ; [#uses=2] - %reg2221 = getelementptr sbyte*** %cast219, long 6 ; [#uses=1] - %reg108 = load sbyte*** %reg2221 ; [#uses=2] - %reg247 = getelementptr sbyte*** %cast219, long 5 ; [#uses=1] - store sbyte** %reg108, sbyte*** %reg247 - ret void -} - diff --git a/test/Transforms/LevelRaise/2002-07-16-RaiseCrash.ll b/test/Transforms/LevelRaise/2002-07-16-RaiseCrash.ll deleted file mode 100644 index ad8a1dc673..0000000000 --- a/test/Transforms/LevelRaise/2002-07-16-RaiseCrash.ll +++ /dev/null @@ -1,53 +0,0 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -raise - - %Tree = type %struct.tree* - %struct.tree = type { int, double, double, %Tree, %Tree, %Tree, %Tree } - -implementation ; Functions: - -void %reverse(%Tree %t) { -bb0: ;[#uses=0] - %cast219 = cast %Tree %t to sbyte*** ; [#uses=7] - %cond220 = seteq sbyte*** %cast219, null ; [#uses=1] - br bool %cond220, label %bb5, label %bb2 - -bb2: ;[#uses=3] - %reg2221 = getelementptr sbyte*** %cast219, long 6 ; [#uses=1] - %reg108 = load sbyte*** %reg2221 ; [#uses=3] - %reg2251 = getelementptr sbyte** %reg108, long 5 ; [#uses=1] - store sbyte* null, sbyte** %reg2251 - %reg2281 = getelementptr sbyte*** %cast219, long 6 ; [#uses=1] - store sbyte** null, sbyte*** %reg2281 - %reg2311 = getelementptr sbyte*** %cast219, long 5 ; [#uses=1] - %reg114 = load sbyte*** %reg2311 ; [#uses=2] - %cond234 = seteq sbyte** %reg114, null ; [#uses=1] - br bool %cond234, label %bb4, label %bb3 - -bb3: ;[#uses=4] - %reg115 = phi sbyte*** [ %cast117, %bb3 ], [ %cast219, %bb2 ] ; [#uses=2] - %reg116 = phi sbyte** [ %cast118, %bb3 ], [ %reg114, %bb2 ] ; [#uses=4] - %reg236 = getelementptr sbyte** %reg116, long 5 ; [#uses=1] - %reg110 = load sbyte** %reg236 ; [#uses=1] - %reg239 = getelementptr sbyte** %reg116, long 5 ; [#uses=1] - %cast241 = cast sbyte*** %reg115 to sbyte* ; [#uses=1] - store sbyte* %cast241, sbyte** %reg239 - %reg242 = getelementptr sbyte*** %reg115, long 6 ; [#uses=1] - store sbyte** %reg116, sbyte*** %reg242 - %cast117 = cast sbyte** %reg116 to sbyte*** ; [#uses=1] - %cast118 = cast sbyte* %reg110 to sbyte** ; [#uses=2] - %cond245 = setne sbyte** %cast118, null ; [#uses=1] - br bool %cond245, label %bb3, label %bb4 - -bb4: ;[#uses=2] - %reg247 = getelementptr sbyte*** %cast219, long 5 ; [#uses=1] - store sbyte** %reg108, sbyte*** %reg247 - %reg250 = getelementptr sbyte** %reg108, long 6 ; [#uses=2] - cast sbyte** %reg250 to sbyte**** ; :0 [#uses=0] - %cast252 = cast sbyte*** %cast219 to sbyte* ; [#uses=1] - store sbyte* %cast252, sbyte** %reg250 - br label %bb5 - -bb5: ;[#uses=2] - ret void -} - diff --git a/test/Transforms/LevelRaise/2002-07-16-RaiseCrash2.ll b/test/Transforms/LevelRaise/2002-07-16-RaiseCrash2.ll deleted file mode 100644 index 9c03684d95..0000000000 --- a/test/Transforms/LevelRaise/2002-07-16-RaiseCrash2.ll +++ /dev/null @@ -1,12 +0,0 @@ -; This crashes raise, with an cast<> failure - -; RUN: llvm-upgrade < %s | llvm-as | opt -raise - -implementation -sbyte* %test(int* %ptr) { - %A = cast int* %ptr to sbyte * - %A = cast sbyte* %A to ulong - %B = add ulong %A, %A - %B = cast ulong %B to sbyte* - ret sbyte * %B -} diff --git a/test/Transforms/LevelRaise/2002-07-16-SourceAndDestCrash.ll b/test/Transforms/LevelRaise/2002-07-16-SourceAndDestCrash.ll deleted file mode 100644 index 18121634dd..0000000000 --- a/test/Transforms/LevelRaise/2002-07-16-SourceAndDestCrash.ll +++ /dev/null @@ -1,21 +0,0 @@ -; This testcase, which was distilled from a HUGE function, causes problems -; because both the source and the destination of the %Y cast are converted -; to a new type, which causes massive problems. - -; RUN: llvm-upgrade < %s | llvm-as | opt -raise -raise-start-inst=W - -int **%test(sbyte **%S) { -BB0: - br label %Loop - -Loop: - %X = phi sbyte* [null , %BB0], [%Z, %Loop] - - %Y = cast sbyte *%X to sbyte ** - %Z = load sbyte** %Y - br bool true, label %Loop, label %Out - -Out: - %W = cast sbyte** %Y to int** - ret int** %W -} diff --git a/test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll b/test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll deleted file mode 100644 index 7ab4ea360d..0000000000 --- a/test/Transforms/LevelRaise/2002-07-18-MissedAllocaRaise.ll +++ /dev/null @@ -1,11 +0,0 @@ -; Looks like we don't raise alloca's like we do mallocs -; XFAIL: * -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep bitcast - -implementation ; Functions: - -int *%X() { - %reg107 = alloca ubyte, uint 4 - %cast213 = cast ubyte* %reg107 to int* - ret int* %cast213 -} diff --git a/test/Transforms/LevelRaise/2002-07-31-AssertionFailure.ll b/test/Transforms/LevelRaise/2002-07-31-AssertionFailure.ll deleted file mode 100644 index d875b1e71c..0000000000 --- a/test/Transforms/LevelRaise/2002-07-31-AssertionFailure.ll +++ /dev/null @@ -1,26 +0,0 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -raise -raise-start-inst=cast271 - - %CON_list = type { %CON_list*, %CON_node* } - %CON_node = type { %DIS_list*, %DIS_list*, int } - %DIS_list = type { %DIS_list*, %DIS_node* } - %DIS_node = type { %CON_list*, %List_o_links*, int } - %List_o_links = type { int, int, int, %List_o_links* } - -implementation ; Functions: - -%CON_node* %build_CON_node(int %reg107) { - br label %bb5 - -bb2: ;[#uses=3] - %reg126 = phi sbyte* [ %reg126, %bb2 ] - br bool true, label %bb2, label %bb5 - -bb5: ;[#uses=2] - %reg125 = phi sbyte* [ %reg126, %bb2], [ null, %0 ] - %reg263 = malloc sbyte*, uint 3 ; [#uses=4] - %reg2641 = getelementptr sbyte** %reg263, long 1 ; [#uses=1] - store sbyte* %reg125, sbyte** %reg2641 - store sbyte* %reg125, sbyte** %reg263 - %cast271 = cast sbyte** %reg263 to %CON_node* ; <%CON_node*> [#uses=1] - ret %CON_node* %cast271 -} diff --git a/test/Transforms/LevelRaise/2002-09-10-PointerAdds.ll b/test/Transforms/LevelRaise/2002-09-10-PointerAdds.ll deleted file mode 100644 index 6a2bc50ef2..0000000000 --- a/test/Transforms/LevelRaise/2002-09-10-PointerAdds.ll +++ /dev/null @@ -1,9 +0,0 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -raise - -int* %test(int* %P, int* %Q) { - %P = cast int* %P to ulong - %Q = cast int* %Q to ulong - %V = add ulong %P, %Q - %V = cast ulong %V to int* - ret int* %V -} diff --git a/test/Transforms/LevelRaise/2002-10-02-SignExtensionProblem.ll b/test/Transforms/LevelRaise/2002-10-02-SignExtensionProblem.ll deleted file mode 100644 index d3b24304b7..0000000000 --- a/test/Transforms/LevelRaise/2002-10-02-SignExtensionProblem.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | grep -v uint | not grep 4294967295 - -%length_code = uninitialized global [256 x ubyte] - -ubyte* %test(uint %length) { - %d = add uint 4294967295, %length - %e = cast uint %d to int - %g = cast int %e to ulong - %j = cast [256 x ubyte]* %length_code to ulong - %l = add ulong %j, %g - %m = cast ulong %l to ubyte* - ret ubyte* %m -} diff --git a/test/Transforms/LevelRaise/2002-10-08-VarArgCall.ll b/test/Transforms/LevelRaise/2002-10-08-VarArgCall.ll deleted file mode 100644 index 6ddcc45c0b..0000000000 --- a/test/Transforms/LevelRaise/2002-10-08-VarArgCall.ll +++ /dev/null @@ -1,9 +0,0 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | grep call | not grep '\.\.\.' - -implementation - -void %test(sbyte* %P) { - %Q = cast sbyte* %P to void (...)* - call void (...)* %Q(sbyte* %P) - ret void -} diff --git a/test/Transforms/LevelRaise/2002-10-08-VarArgCallInfLoop.ll b/test/Transforms/LevelRaise/2002-10-08-VarArgCallInfLoop.ll deleted file mode 100644 index a7ac87144f..0000000000 --- a/test/Transforms/LevelRaise/2002-10-08-VarArgCallInfLoop.ll +++ /dev/null @@ -1,10 +0,0 @@ -; Due to a recent change, this testcase now sends the raise pass into an infinite loop -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise - -implementation - -void %test(sbyte* %P, void(...) * %F) { - call void (...)* %F(sbyte* %P) - ret void -} diff --git a/test/Transforms/LevelRaise/2002-11-04-ConstantSharing.ll b/test/Transforms/LevelRaise/2002-11-04-ConstantSharing.ll deleted file mode 100644 index 4e4b806b44..0000000000 --- a/test/Transforms/LevelRaise/2002-11-04-ConstantSharing.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llvm-as < 2002-11-04-ConstantSharing.ll | opt -raise | llvm-dis | notcast - -implementation - -bool %test(int *%X, uint* %Y) { - %A = cast int* %X to sbyte* - %B = cast uint* %Y to sbyte* - %c1 = seteq sbyte* %A, null - %c2 = seteq sbyte* %B, null - %c = and bool %c1, %c2 - ret bool %c -} diff --git a/test/Transforms/LevelRaise/2002-11-13-PointerFunction.ll b/test/Transforms/LevelRaise/2002-11-13-PointerFunction.ll deleted file mode 100644 index 2d51811501..0000000000 --- a/test/Transforms/LevelRaise/2002-11-13-PointerFunction.ll +++ /dev/null @@ -1,10 +0,0 @@ -; This testcase should be able to eliminate at least one of the casts. -; -; RUN: llvm-upgrade < %s | llvm-as | opt -raise | llvm-dis | not grep 'REMOVE' - -int %foo(sbyte * %PF) { - %UPF = cast sbyte* %PF to uint()* - %Ret = call uint %UPF() - %REMOVE = cast uint %Ret to int - ret int %REMOVE -} diff --git a/test/Transforms/LevelRaise/2003-01-22-GEPProblem.ll b/test/Transforms/LevelRaise/2003-01-22-GEPProblem.ll deleted file mode 100644 index 540ffa26b9..0000000000 --- a/test/Transforms/LevelRaise/2003-01-22-GEPProblem.ll +++ /dev/null @@ -1,22 +0,0 @@ -; Testcase reduced from 197.parser by bugpoint -; RUN: llvm-upgrade < %s | llvm-as | opt -raise -raise-start-inst=cast455 > /dev/null - -void %conjunction_prune() { -;