[llvm-commits] [llvm] r133700 - in /llvm/trunk: include/llvm/ include/llvm/Support/ lib/MC/ lib/Target/CppBackend/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/
Eric Christopher
echristo at apple.com
Wed Jun 22 23:24:53 PDT 2011
Author: echristo
Date: Thu Jun 23 01:24:52 2011
New Revision: 133700
URL: http://llvm.org/viewvc/llvm-project?rev=133700&view=rev
Log:
Revert r133513:
"Reinstate r133435 and r133449 (reverted in r133499) now that the clang
self-hosted build failure has been fixed (r133512)."
Due to some additional warnings.
Modified:
llvm/trunk/include/llvm/BasicBlock.h
llvm/trunk/include/llvm/Instructions.h
llvm/trunk/include/llvm/Support/CFG.h
llvm/trunk/include/llvm/Use.h
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp
llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
llvm/trunk/lib/Transforms/Utils/Local.cpp
llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp
llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp
llvm/trunk/lib/VMCore/BasicBlock.cpp
llvm/trunk/lib/VMCore/Instructions.cpp
llvm/trunk/lib/VMCore/User.cpp
llvm/trunk/lib/VMCore/Value.cpp
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/include/llvm/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/BasicBlock.h Thu Jun 23 01:24:52 2011
@@ -110,7 +110,7 @@
Function *getParent() { return Parent; }
/// use_back - Specialize the methods defined in Value, as we know that an
- /// BasicBlock can only be used by Users (specifically terminators
+ /// BasicBlock can only be used by Users (specifically PHI nodes, terminators,
/// and BlockAddress's).
User *use_back() { return cast<User>(*use_begin());}
const User *use_back() const { return cast<User>(*use_begin());}
@@ -248,10 +248,6 @@
/// other than direct branches, switches, etc. to it.
bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
- /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors
- /// to refer to basic block New instead of to us.
- void replaceSuccessorsPhiUsesWith(BasicBlock *New);
-
private:
/// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
/// objects using it. This is almost always 0, sometimes one, possibly but
Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Thu Jun 23 01:24:52 2011
@@ -1814,7 +1814,7 @@
explicit PHINode(const Type *Ty, unsigned NumReservedValues,
const Twine &NameStr = "", Instruction *InsertBefore = 0)
: Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
- ReservedSpace(NumReservedValues) {
+ ReservedSpace(NumReservedValues * 2) {
setName(NameStr);
OperandList = allocHungoffUses(ReservedSpace);
}
@@ -1822,16 +1822,11 @@
PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
BasicBlock *InsertAtEnd)
: Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
- ReservedSpace(NumReservedValues) {
+ ReservedSpace(NumReservedValues * 2) {
setName(NameStr);
OperandList = allocHungoffUses(ReservedSpace);
}
protected:
- // allocHungoffUses - this is more complicated than the generic
- // User::allocHungoffUses, because we have to allocate Uses for the incoming
- // values and pointers to the incoming blocks, all in one allocation.
- Use *allocHungoffUses(unsigned) const;
-
virtual PHINode *clone_impl() const;
public:
/// Constructors - NumReservedValues is a hint for the number of incoming
@@ -1850,55 +1845,32 @@
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- // Block iterator interface. This provides access to the list of incoming
- // basic blocks, which parallels the list of incoming values.
-
- typedef BasicBlock **block_iterator;
- typedef BasicBlock * const *const_block_iterator;
-
- block_iterator block_begin() {
- Use::UserRef *ref =
- reinterpret_cast<Use::UserRef*>(op_begin() + ReservedSpace);
- return reinterpret_cast<block_iterator>(ref + 1);
- }
-
- const_block_iterator block_begin() const {
- const Use::UserRef *ref =
- reinterpret_cast<const Use::UserRef*>(op_begin() + ReservedSpace);
- return reinterpret_cast<const_block_iterator>(ref + 1);
- }
-
- block_iterator block_end() {
- return block_begin() + getNumOperands();
- }
-
- const_block_iterator block_end() const {
- return block_begin() + getNumOperands();
- }
-
/// getNumIncomingValues - Return the number of incoming edges
///
- unsigned getNumIncomingValues() const { return getNumOperands(); }
+ unsigned getNumIncomingValues() const { return getNumOperands()/2; }
/// getIncomingValue - Return incoming value number x
///
Value *getIncomingValue(unsigned i) const {
- return getOperand(i);
+ assert(i*2 < getNumOperands() && "Invalid value number!");
+ return getOperand(i*2);
}
void setIncomingValue(unsigned i, Value *V) {
- setOperand(i, V);
+ assert(i*2 < getNumOperands() && "Invalid value number!");
+ setOperand(i*2, V);
}
static unsigned getOperandNumForIncomingValue(unsigned i) {
- return i;
+ return i*2;
}
static unsigned getIncomingValueNumForOperand(unsigned i) {
- return i;
+ assert(i % 2 == 0 && "Invalid incoming-value operand index!");
+ return i/2;
}
/// getIncomingBlock - Return incoming basic block number @p i.
///
BasicBlock *getIncomingBlock(unsigned i) const {
- return block_begin()[i];
+ return cast<BasicBlock>(getOperand(i*2+1));
}
/// getIncomingBlock - Return incoming basic block corresponding
@@ -1906,7 +1878,7 @@
///
BasicBlock *getIncomingBlock(const Use &U) const {
assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?");
- return getIncomingBlock(&U - op_begin());
+ return cast<BasicBlock>((&U + 1)->get());
}
/// getIncomingBlock - Return incoming basic block corresponding
@@ -1917,8 +1889,16 @@
return getIncomingBlock(I.getUse());
}
+
void setIncomingBlock(unsigned i, BasicBlock *BB) {
- block_begin()[i] = BB;
+ setOperand(i*2+1, (Value*)BB);
+ }
+ static unsigned getOperandNumForIncomingBlock(unsigned i) {
+ return i*2+1;
+ }
+ static unsigned getIncomingBlockNumForOperand(unsigned i) {
+ assert(i % 2 == 1 && "Invalid incoming-block operand index!");
+ return i/2;
}
/// addIncoming - Add an incoming value to the end of the PHI list
@@ -1928,12 +1908,13 @@
assert(BB && "PHI node got a null basic block!");
assert(getType() == V->getType() &&
"All operands to PHI node must be the same type as the PHI node!");
- if (NumOperands == ReservedSpace)
+ unsigned OpNo = NumOperands;
+ if (OpNo+2 > ReservedSpace)
growOperands(); // Get more space!
// Initialize some new operands.
- ++NumOperands;
- setIncomingValue(NumOperands - 1, V);
- setIncomingBlock(NumOperands - 1, BB);
+ NumOperands = OpNo+2;
+ OperandList[OpNo] = V;
+ OperandList[OpNo+1] = (Value*)BB;
}
/// removeIncomingValue - Remove an incoming value. This is useful if a
@@ -1956,16 +1937,14 @@
/// block in the value list for this PHI. Returns -1 if no instance.
///
int getBasicBlockIndex(const BasicBlock *BB) const {
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (block_begin()[i] == BB)
- return i;
+ Use *OL = OperandList;
+ for (unsigned i = 0, e = getNumOperands(); i != e; i += 2)
+ if (OL[i+1].get() == (const Value*)BB) return i/2;
return -1;
}
Value *getIncomingValueForBlock(const BasicBlock *BB) const {
- int Idx = getBasicBlockIndex(BB);
- assert(Idx >= 0 && "Invalid basic block argument!");
- return getIncomingValue(Idx);
+ return getIncomingValue(getBasicBlockIndex(BB));
}
/// hasConstantValue - If the specified PHI node always merges together the
Modified: llvm/trunk/include/llvm/Support/CFG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CFG.h?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/CFG.h (original)
+++ llvm/trunk/include/llvm/Support/CFG.h Thu Jun 23 01:24:52 2011
@@ -33,7 +33,7 @@
USE_iterator It;
inline void advancePastNonTerminators() {
- // Loop to ignore non terminator uses (for example BlockAddresses).
+ // Loop to ignore non terminator uses (for example PHI nodes).
while (!It.atEnd() && !isa<TerminatorInst>(*It))
++It;
}
Modified: llvm/trunk/include/llvm/Use.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Use.h?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Use.h (original)
+++ llvm/trunk/include/llvm/Use.h Thu Jun 23 01:24:52 2011
@@ -112,16 +112,13 @@
Use *getNext() const { return Next; }
- /// initTags - initialize the waymarking tags on an array of Uses, so that
- /// getUser() can find the User from any of those Uses.
- static Use *initTags(Use *Start, Use *Stop);
-
/// zap - This is used to destroy Use operands when the number of operands of
/// a User changes.
static void zap(Use *Start, const Use *Stop, bool del = false);
private:
const Use* getImpliedUser() const;
+ static Use *initTags(Use *Start, Use *Stop);
Value *Val;
Use *Next;
@@ -143,6 +140,7 @@
}
friend class Value;
+ friend class User;
};
// simplify_type - Allow clients to treat uses just like values when using
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Jun 23 01:24:52 2011
@@ -1119,7 +1119,7 @@
} else {
// Otherwise, write out in binary.
OS << "0b";
- for (unsigned j = 8; j--;) {
+ for (int j = 7; j >= 0; j--) {
unsigned Bit = (Code[i] >> j) & 1;
unsigned FixupBit;
@@ -1128,9 +1128,9 @@
else
FixupBit = i * 8 + (7-j);
- if (uint8_t MapEntry = FixupMap[FixupBit]) {
- assert(Bit == 0 && "Encoder wrote into fixed up bit!");
- OS << char('A' + MapEntry - 1);
+ if (uint8_t FixupMapEntry = FixupMap[FixupBit]) {
+ //assert(Bit == 0 && "Encoder wrote into fixed up bit!");
+ OS << char('A' + FixupMapEntry - 1);
} else
OS << Bit;
}
Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original)
+++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Thu Jun 23 01:24:52 2011
@@ -1356,7 +1356,7 @@
for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) {
Out << iName << "->addIncoming("
<< opNames[PHINode::getOperandNumForIncomingValue(i)] << ", "
- << getOpName(phi->getIncomingBlock(i)) << ");";
+ << opNames[PHINode::getOperandNumForIncomingBlock(i)] << ");";
nl(Out);
}
break;
Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Thu Jun 23 01:24:52 2011
@@ -1021,10 +1021,6 @@
while (PHINode *PN = dyn_cast<PHINode>(Succ->begin()))
ReplaceUsesOfWith(PN, PN->getIncomingValue(0), Worklist, L, LPM);
- // If Succ has any successors with PHI nodes, update them to have
- // entries coming from Pred instead of Succ.
- Succ->replaceAllUsesWith(Pred);
-
// Move all of the successor contents from Succ to Pred.
Pred->getInstList().splice(BI, Succ->getInstList(), Succ->begin(),
Succ->end());
@@ -1032,6 +1028,10 @@
BI->eraseFromParent();
RemoveFromWorklist(BI, Worklist);
+ // If Succ has any successors with PHI nodes, update them to have
+ // entries coming from Pred instead of Succ.
+ Succ->replaceAllUsesWith(Pred);
+
// Remove Succ from the loop tree.
LI->removeBlock(Succ);
LPM->deleteSimpleAnalysisValue(Succ, L);
Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Thu Jun 23 01:24:52 2011
@@ -153,13 +153,13 @@
// Delete the unconditional branch from the predecessor...
PredBB->getInstList().pop_back();
+ // Move all definitions in the successor to the predecessor...
+ PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
+
// Make all PHI nodes that referred to BB now refer to Pred as their
// source...
BB->replaceAllUsesWith(PredBB);
- // Move all definitions in the successor to the predecessor...
- PredBB->getInstList().splice(PredBB->end(), BB->getInstList());
-
// Inherit predecessors name if it exists.
if (!PredBB->hasName())
PredBB->takeName(BB);
Modified: llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BreakCriticalEdges.cpp Thu Jun 23 01:24:52 2011
@@ -193,22 +193,44 @@
// If there are any PHI nodes in DestBB, we need to update them so that they
// merge incoming values from NewBB instead of from TIBB.
- {
- unsigned BBIdx = 0;
- for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
- // We no longer enter through TIBB, now we come in through NewBB.
- // Revector exactly one entry in the PHI node that used to come from
- // TIBB to come from NewBB.
- PHINode *PN = cast<PHINode>(I);
-
- // Reuse the previous value of BBIdx if it lines up. In cases where we
- // have multiple phi nodes with *lots* of predecessors, this is a speed
- // win because we don't have to scan the PHI looking for TIBB. This
- // happens because the BB list of PHI nodes are usually in the same
- // order.
- if (PN->getIncomingBlock(BBIdx) != TIBB)
- BBIdx = PN->getBasicBlockIndex(TIBB);
- PN->setIncomingBlock(BBIdx, NewBB);
+ if (PHINode *APHI = dyn_cast<PHINode>(DestBB->begin())) {
+ // This conceptually does:
+ // foreach (PHINode *PN in DestBB)
+ // PN->setIncomingBlock(PN->getIncomingBlock(TIBB), NewBB);
+ // but is optimized for two cases.
+
+ if (APHI->getNumIncomingValues() <= 8) { // Small # preds case.
+ unsigned BBIdx = 0;
+ for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
+ // We no longer enter through TIBB, now we come in through NewBB.
+ // Revector exactly one entry in the PHI node that used to come from
+ // TIBB to come from NewBB.
+ PHINode *PN = cast<PHINode>(I);
+
+ // Reuse the previous value of BBIdx if it lines up. In cases where we
+ // have multiple phi nodes with *lots* of predecessors, this is a speed
+ // win because we don't have to scan the PHI looking for TIBB. This
+ // happens because the BB list of PHI nodes are usually in the same
+ // order.
+ if (PN->getIncomingBlock(BBIdx) != TIBB)
+ BBIdx = PN->getBasicBlockIndex(TIBB);
+ PN->setIncomingBlock(BBIdx, NewBB);
+ }
+ } else {
+ // However, the foreach loop is slow for blocks with lots of predecessors
+ // because PHINode::getIncomingBlock is O(n) in # preds. Instead, walk
+ // the user list of TIBB to find the PHI nodes.
+ SmallPtrSet<PHINode*, 16> UpdatedPHIs;
+
+ for (Value::use_iterator UI = TIBB->use_begin(), E = TIBB->use_end();
+ UI != E; ) {
+ Value::use_iterator Use = UI++;
+ if (PHINode *PN = dyn_cast<PHINode>(*Use)) {
+ // Remove one entry from each PHI.
+ if (PN->getParent() == DestBB && UpdatedPHIs.insert(PN))
+ PN->setOperand(Use.getOperandNo(), NewBB);
+ }
+ }
}
}
Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Thu Jun 23 01:24:52 2011
@@ -572,12 +572,12 @@
// removed, so we just need to splice the blocks.
BI->eraseFromParent();
- // Make all PHI nodes that referred to Dest now refer to I as their source.
- Dest->replaceAllUsesWith(I);
-
// Move all the instructions in the succ to the pred.
I->getInstList().splice(I->end(), Dest->getInstList());
+ // Make all PHI nodes that referred to Dest now refer to I as their source.
+ Dest->replaceAllUsesWith(I);
+
// Remove the dest block.
Dest->eraseFromParent();
Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Thu Jun 23 01:24:52 2011
@@ -1097,15 +1097,15 @@
TheCall->replaceAllUsesWith(Returns[0]->getReturnValue());
}
- // Update PHI nodes that use the ReturnBB to use the AfterCallBB.
- BasicBlock *ReturnBB = Returns[0]->getParent();
- ReturnBB->replaceAllUsesWith(AfterCallBB);
-
// Splice the code from the return block into the block that it will return
// to, which contains the code that was after the call.
+ BasicBlock *ReturnBB = Returns[0]->getParent();
AfterCallBB->getInstList().splice(AfterCallBB->begin(),
ReturnBB->getInstList());
+ // Update PHI nodes that use the ReturnBB to use the AfterCallBB.
+ ReturnBB->replaceAllUsesWith(AfterCallBB);
+
// Delete the return instruction now and empty ReturnBB now.
Returns[0]->eraseFromParent();
ReturnBB->eraseFromParent();
@@ -1125,8 +1125,8 @@
// Splice the code entry block into calling block, right before the
// unconditional branch.
- CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes
OrigBB->getInstList().splice(Br, CalleeEntry->getInstList());
+ CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes
// Remove the unconditional branch.
OrigBB->getInstList().erase(Br);
Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Thu Jun 23 01:24:52 2011
@@ -427,6 +427,10 @@
BasicBlock *PredBB = DestBB->getSinglePredecessor();
assert(PredBB && "Block doesn't have a single predecessor!");
+ // Splice all the instructions from PredBB to DestBB.
+ PredBB->getTerminator()->eraseFromParent();
+ DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList());
+
// Zap anything that took the address of DestBB. Not doing this will give the
// address an invalid value.
if (DestBB->hasAddressTaken()) {
@@ -441,10 +445,6 @@
// Anything that branched to PredBB now branches to DestBB.
PredBB->replaceAllUsesWith(DestBB);
- // Splice all the instructions from PredBB to DestBB.
- PredBB->getTerminator()->eraseFromParent();
- DestBB->getInstList().splice(DestBB->begin(), PredBB->getInstList());
-
if (P) {
DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>();
if (DT) {
@@ -660,17 +660,12 @@
// them, which helps expose duplicates, but we have to check all the
// operands to be safe in case instcombine hasn't run.
uintptr_t Hash = 0;
- // This hash algorithm is quite weak as hash functions go, but it seems
- // to do a good enough job for this particular purpose, and is very quick.
for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) {
+ // This hash algorithm is quite weak as hash functions go, but it seems
+ // to do a good enough job for this particular purpose, and is very quick.
Hash ^= reinterpret_cast<uintptr_t>(static_cast<Value *>(*I));
Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7));
}
- for (PHINode::block_iterator I = PN->block_begin(), E = PN->block_end();
- I != E; ++I) {
- Hash ^= reinterpret_cast<uintptr_t>(static_cast<BasicBlock *>(*I));
- Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7));
- }
// Avoid colliding with the DenseMap sentinels ~0 and ~0-1.
Hash >>= 1;
// If we've never seen this hash value before, it's a unique PHI.
Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Thu Jun 23 01:24:52 2011
@@ -47,14 +47,6 @@
if (It != VMap.end())
I->setOperand(op, It->second);
}
-
- if (PHINode *PN = dyn_cast<PHINode>(I)) {
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- ValueToValueMapTy::iterator It = VMap.find(PN->getIncomingBlock(i));
- if (It != VMap.end())
- PN->setIncomingBlock(i, cast<BasicBlock>(It->second));
- }
- }
}
/// FoldBlockIntoPredecessor - Folds a basic block into its predecessor if it
@@ -83,13 +75,13 @@
// Delete the unconditional branch from the predecessor...
OnlyPred->getInstList().pop_back();
+ // Move all definitions in the successor to the predecessor...
+ OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList());
+
// Make all PHI nodes that referred to BB now refer to Pred as their
// source...
BB->replaceAllUsesWith(OnlyPred);
- // Move all definitions in the successor to the predecessor...
- OnlyPred->getInstList().splice(OnlyPred->end(), BB->getInstList());
-
std::string OldName = BB->getName();
// Erase basic block from the function...
@@ -129,14 +121,14 @@
BasicBlock *Header = L->getHeader();
BranchInst *BI = dyn_cast<BranchInst>(LatchBlock->getTerminator());
-
+
if (!BI || BI->isUnconditional()) {
// The loop-rotate pass can be helpful to avoid this in many cases.
DEBUG(dbgs() <<
" Can't unroll; loop not terminated by a conditional branch.\n");
return false;
}
-
+
if (Header->hasAddressTaken()) {
// The loop-rotate pass can be helpful to avoid this in many cases.
DEBUG(dbgs() <<
@@ -210,7 +202,7 @@
for (BasicBlock::iterator I = Header->begin(); isa<PHINode>(I); ++I) {
PHINode *PN = cast<PHINode>(I);
OrigPHINode.push_back(PN);
- if (Instruction *I =
+ if (Instruction *I =
dyn_cast<Instruction>(PN->getIncomingValueForBlock(LatchBlock)))
if (L->contains(I))
LastValueMap[I] = I;
@@ -223,7 +215,7 @@
for (unsigned It = 1; It != Count; ++It) {
std::vector<BasicBlock*> NewBlocks;
-
+
for (std::vector<BasicBlock*>::iterator BB = LoopBlocks.begin(),
E = LoopBlocks.end(); BB != E; ++BB) {
ValueToValueMapTy VMap;
@@ -255,14 +247,16 @@
// the successor of the latch block. The successor of the exit block will
// be updated specially after unrolling all the way.
if (*BB != LatchBlock)
- for (succ_iterator SI = succ_begin(*BB), SE = succ_end(*BB); SI != SE;
- ++SI)
- if (!L->contains(*SI))
- for (BasicBlock::iterator BBI = (*SI)->begin();
- PHINode *phi = dyn_cast<PHINode>(BBI); ++BBI) {
- Value *Incoming = phi->getIncomingValueForBlock(*BB);
- phi->addIncoming(Incoming, New);
- }
+ for (Value::use_iterator UI = (*BB)->use_begin(), UE = (*BB)->use_end();
+ UI != UE;) {
+ Instruction *UseInst = cast<Instruction>(*UI);
+ ++UI;
+ if (isa<PHINode>(UseInst) && !L->contains(UseInst)) {
+ PHINode *phi = cast<PHINode>(UseInst);
+ Value *Incoming = phi->getIncomingValueForBlock(*BB);
+ phi->addIncoming(Incoming, New);
+ }
+ }
// Keep track of new headers and latches as we create them, so that
// we can insert the proper branches later.
@@ -282,32 +276,36 @@
NewBlocks.push_back(New);
}
-
+
// Remap all instructions in the most recent iteration
for (unsigned i = 0; i < NewBlocks.size(); ++i)
for (BasicBlock::iterator I = NewBlocks[i]->begin(),
E = NewBlocks[i]->end(); I != E; ++I)
::RemapInstruction(I, LastValueMap);
}
-
+
// The latch block exits the loop. If there are any PHI nodes in the
// successor blocks, update them to use the appropriate values computed as the
// last iteration of the loop.
if (Count != 1) {
+ SmallPtrSet<PHINode*, 8> Users;
+ for (Value::use_iterator UI = LatchBlock->use_begin(),
+ UE = LatchBlock->use_end(); UI != UE; ++UI)
+ if (PHINode *phi = dyn_cast<PHINode>(*UI))
+ Users.insert(phi);
+
BasicBlock *LastIterationBB = cast<BasicBlock>(LastValueMap[LatchBlock]);
- for (succ_iterator SI = succ_begin(LatchBlock), SE = succ_end(LatchBlock);
+ for (SmallPtrSet<PHINode*,8>::iterator SI = Users.begin(), SE = Users.end();
SI != SE; ++SI) {
- for (BasicBlock::iterator BBI = (*SI)->begin();
- PHINode *PN = dyn_cast<PHINode>(BBI); ++BBI) {
- Value *InVal = PN->removeIncomingValue(LatchBlock, false);
- // If this value was defined in the loop, take the value defined by the
- // last iteration of the loop.
- if (Instruction *InValI = dyn_cast<Instruction>(InVal)) {
- if (L->contains(InValI))
- InVal = LastValueMap[InVal];
- }
- PN->addIncoming(InVal, LastIterationBB);
+ PHINode *PN = *SI;
+ Value *InVal = PN->removeIncomingValue(LatchBlock, false);
+ // If this value was defined in the loop, take the value defined by the
+ // last iteration of the loop.
+ if (Instruction *InValI = dyn_cast<Instruction>(InVal)) {
+ if (L->contains(InValI))
+ InVal = LastValueMap[InVal];
}
+ PN->addIncoming(InVal, LastIterationBB);
}
}
@@ -354,19 +352,14 @@
// Replace the conditional branch with an unconditional one.
BranchInst::Create(Dest, Term);
Term->eraseFromParent();
- }
- }
-
- // Merge adjacent basic blocks, if possible.
- for (unsigned i = 0, e = Latches.size(); i != e; ++i) {
- BranchInst *Term = cast<BranchInst>(Latches[i]->getTerminator());
- if (Term->isUnconditional()) {
- BasicBlock *Dest = Term->getSuccessor(0);
- if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI))
+ // Merge adjacent basic blocks, if possible.
+ if (BasicBlock *Fold = FoldBlockIntoPredecessor(Dest, LI)) {
std::replace(Latches.begin(), Latches.end(), Dest, Fold);
+ std::replace(Headers.begin(), Headers.end(), Dest, Fold);
+ }
}
}
-
+
// At this point, the code is well formed. We now do a quick sweep over the
// inserted code, doing constant propagation and dead code elimination as we
// go.
Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Thu Jun 23 01:24:52 2011
@@ -16,7 +16,6 @@
#include "llvm/Type.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
-#include "llvm/Instructions.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
@@ -129,19 +128,6 @@
"Referenced value not in value map!");
}
- // Remap phi nodes' incoming blocks.
- if (PHINode *PN = dyn_cast<PHINode>(I)) {
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags);
- // If we aren't ignoring missing entries, assert that something happened.
- if (V != 0)
- PN->setIncomingBlock(i, cast<BasicBlock>(V));
- else
- assert((Flags & RF_IgnoreMissingEntries) &&
- "Referenced block not in value map!");
- }
- }
-
// Remap attached metadata.
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
I->getAllMetadata(MDs);
Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/BasicBlock.cpp (original)
+++ llvm/trunk/lib/VMCore/BasicBlock.cpp Thu Jun 23 01:24:52 2011
@@ -308,19 +308,3 @@
return New;
}
-void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) {
- TerminatorInst *TI = getTerminator();
- if (!TI)
- // Cope with being called on a BasicBlock that doesn't have a terminator
- // yet. Clang's CodeGenFunction::EmitReturnBlock() likes to do this.
- return;
- for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) {
- BasicBlock *Succ = TI->getSuccessor(i);
- for (iterator II = Succ->begin(); PHINode *PN = dyn_cast<PHINode>(II);
- ++II) {
- int i;
- while ((i = PN->getBasicBlockIndex(this)) >= 0)
- PN->setIncomingBlock(i, New);
- }
- }
-}
Modified: llvm/trunk/lib/VMCore/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Instructions.cpp (original)
+++ llvm/trunk/lib/VMCore/Instructions.cpp Thu Jun 23 01:24:52 2011
@@ -87,8 +87,11 @@
: Instruction(PN.getType(), Instruction::PHI,
allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()),
ReservedSpace(PN.getNumOperands()) {
- std::copy(PN.op_begin(), PN.op_end(), op_begin());
- std::copy(PN.block_begin(), PN.block_end(), block_begin());
+ Use *OL = OperandList;
+ for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
+ OL[i] = PN.getOperand(i);
+ OL[i+1] = PN.getOperand(i+1);
+ }
SubclassOptionalData = PN.SubclassOptionalData;
}
@@ -96,37 +99,31 @@
dropHungoffUses();
}
-Use *PHINode::allocHungoffUses(unsigned N) const {
- // Allocate the array of Uses of the incoming values, followed by a pointer
- // (with bottom bit set) to the User, followed by the array of pointers to
- // the incoming basic blocks.
- size_t size = N * sizeof(Use) + sizeof(Use::UserRef)
- + N * sizeof(BasicBlock*);
- Use *Begin = static_cast<Use*>(::operator new(size));
- Use *End = Begin + N;
- (void) new(End) Use::UserRef(const_cast<PHINode*>(this), 1);
- return Use::initTags(Begin, End);
-}
-
// removeIncomingValue - Remove an incoming value. This is useful if a
// predecessor basic block is deleted.
Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
- Value *Removed = getIncomingValue(Idx);
+ unsigned NumOps = getNumOperands();
+ Use *OL = OperandList;
+ assert(Idx*2 < NumOps && "BB not in PHI node!");
+ Value *Removed = OL[Idx*2];
// Move everything after this operand down.
//
// FIXME: we could just swap with the end of the list, then erase. However,
- // clients might not expect this to happen. The code as it is thrashes the
+ // client might not expect this to happen. The code as it is thrashes the
// use/def lists, which is kinda lame.
- std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx);
- std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx);
+ for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) {
+ OL[i-2] = OL[i];
+ OL[i-2+1] = OL[i+1];
+ }
// Nuke the last value.
- Op<-1>().set(0);
- --NumOperands;
+ OL[NumOps-2].set(0);
+ OL[NumOps-2+1].set(0);
+ NumOperands = NumOps-2;
// If the PHI node is dead, because it has zero entries, nuke it now.
- if (getNumOperands() == 0 && DeletePHIIfEmpty) {
+ if (NumOps == 2 && DeletePHIIfEmpty) {
// If anyone is using this PHI, make them use a dummy value instead...
replaceAllUsesWith(UndefValue::get(getType()));
eraseFromParent();
@@ -140,18 +137,15 @@
///
void PHINode::growOperands() {
unsigned e = getNumOperands();
- unsigned NumOps = e + e / 2;
- if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common.
-
- Use *OldOps = op_begin();
- BasicBlock **OldBlocks = block_begin();
+ // Multiply by 1.5 and round down so the result is still even.
+ unsigned NumOps = e + e / 4 * 2;
+ if (NumOps < 4) NumOps = 4; // 4 op PHI nodes are VERY common.
ReservedSpace = NumOps;
- OperandList = allocHungoffUses(ReservedSpace);
-
- std::copy(OldOps, OldOps + e, op_begin());
- std::copy(OldBlocks, OldBlocks + e, block_begin());
-
+ Use *OldOps = OperandList;
+ Use *NewOps = allocHungoffUses(NumOps);
+ std::copy(OldOps, OldOps + e, NewOps);
+ OperandList = NewOps;
Use::zap(OldOps, OldOps + e, true);
}
Modified: llvm/trunk/lib/VMCore/User.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/User.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/User.cpp (original)
+++ llvm/trunk/lib/VMCore/User.cpp Thu Jun 23 01:24:52 2011
@@ -40,10 +40,8 @@
//===----------------------------------------------------------------------===//
Use *User::allocHungoffUses(unsigned N) const {
- // Allocate the array of Uses, followed by a pointer (with bottom bit set) to
- // the User.
- size_t size = N * sizeof(Use) + sizeof(Use::UserRef);
- Use *Begin = static_cast<Use*>(::operator new(size));
+ Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N
+ + sizeof(Use::UserRef)));
Use *End = Begin + N;
(void) new(End) Use::UserRef(const_cast<User*>(this), 1);
return Use::initTags(Begin, End);
Modified: llvm/trunk/lib/VMCore/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Value.cpp (original)
+++ llvm/trunk/lib/VMCore/Value.cpp Thu Jun 23 01:24:52 2011
@@ -305,9 +305,6 @@
U.set(New);
}
-
- if (BasicBlock *BB = dyn_cast<BasicBlock>(this))
- BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New));
}
void Value::replaceAllUsesWith(Value *New) {
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=133700&r1=133699&r2=133700&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Thu Jun 23 01:24:52 2011
@@ -1139,6 +1139,9 @@
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
Assert1(PN.getType() == PN.getIncomingValue(i)->getType(),
"PHI node operands are not the same type as the result!", &PN);
+ Assert1(isa<BasicBlock>(PN.getOperand(
+ PHINode::getOperandNumForIncomingBlock(i))),
+ "PHI node incoming block is not a BasicBlock!", &PN);
}
// All other PHI node constraints are checked in the visitBasicBlock method.
More information about the llvm-commits
mailing list