#include "llvm/iMemory.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
-#include "Support/StringExtras.h"
+#include "Support/Debug.h"
#include "Support/Statistic.h"
+#include "Support/StringExtras.h"
namespace {
Statistic<> NumReplaced("scalarrepl", "Number of alloca's broken up");
struct SROA : public FunctionPass {
bool runOnFunction(Function &F);
+ // getAnalysisUsage - This pass does not require any passes, but we know it
+ // will not alter the CFG, so say so.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesCFG();
+ }
+
private:
- bool isSafeArrayElementUse(Value *Ptr);
+ bool isSafeElementUse(Value *Ptr);
bool isSafeUseOfAllocation(Instruction *User);
bool isSafeStructAllocaToPromote(AllocationInst *AI);
bool isSafeArrayAllocaToPromote(AllocationInst *AI);
Instruction *User = cast<Instruction>(*I);
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
// We now know that the GEP is of the form: GEP <ptr>, 0, <cst>
- uint64_t Idx;
- if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(GEPI->getOperand(2)))
- Idx = CSI->getValue();
- else
- Idx = cast<ConstantUInt>(GEPI->getOperand(2))->getValue();
+ uint64_t Idx = cast<ConstantInt>(GEPI->getOperand(2))->getRawValue();
assert(Idx < ElementAllocas.size() && "Index out of range?");
AllocaInst *AllocaToUse = ElementAllocas[Idx];
return true;
}
-
-/// isSafeArrayElementUse - Check to see if this use is an allowed use for a
+/// isSafeElementUse - Check to see if this use is an allowed use for a
/// getelementptr instruction of an array aggregate allocation.
///
-bool SROA::isSafeArrayElementUse(Value *Ptr) {
+bool SROA::isSafeElementUse(Value *Ptr) {
for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end();
I != E; ++I) {
Instruction *User = cast<Instruction>(*I);
if (!isa<Constant>(GEP->getOperand(1)) ||
!cast<Constant>(GEP->getOperand(1))->isNullValue())
return false; // Using pointer arithmetic to navigate the array...
-
- // Check to see if there are any structure indexes involved in this GEP.
- // If so, then we can safely break the array up until at least the
- // structure.
- for (unsigned i = 2, e = GEP->getNumOperands(); i != e; ++i)
- if (GEP->getOperand(i)->getType()->isUnsigned())
- break;
}
- return isSafeArrayElementUse(GEP);
+ return isSafeElementUse(GEP);
}
default:
DEBUG(std::cerr << " Transformation preventing inst: " << *User);
// the users are safe to transform.
//
for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
- I != E; ++I)
+ I != E; ++I) {
if (!isSafeUseOfAllocation(cast<Instruction>(*I))) {
DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: "
<< *I);
return false;
}
+
+ // Pedantic check to avoid breaking broken programs...
+ if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*I))
+ if (GEPI->getNumOperands() == 3 && !isSafeElementUse(GEPI))
+ return false;
+ }
return true;
}
// P = &A[0]; P = P + 1
// is legal, and should prevent promotion.
//
- if (!isSafeArrayElementUse(GEPI)) {
+ if (!isSafeElementUse(GEPI)) {
DEBUG(std::cerr << "Cannot transform: " << *AI
<< " due to uses of user: " << *GEPI);
return false;