diff options
author | Jay Foad <jay.foad@gmail.com> | 2011-06-21 10:33:19 +0000 |
---|---|---|
committer | Jay Foad <jay.foad@gmail.com> | 2011-06-21 10:33:19 +0000 |
commit | cd35e09a4a3c640b9da0b1dfe3548a605c929ae5 (patch) | |
tree | e30d6c21f872a780cbcf44458e2b70489803eb20 /lib/VMCore | |
parent | 69254f67a54656ebf88fe854d0e8bf7fc58abda6 (diff) | |
download | external_llvm-cd35e09a4a3c640b9da0b1dfe3548a605c929ae5.zip external_llvm-cd35e09a4a3c640b9da0b1dfe3548a605c929ae5.tar.gz external_llvm-cd35e09a4a3c640b9da0b1dfe3548a605c929ae5.tar.bz2 |
Reinstate r133435 and r133449 (reverted in r133499) now that the clang
self-hosted build failure has been fixed (r133512).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133513 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/BasicBlock.cpp | 16 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 56 | ||||
-rw-r--r-- | lib/VMCore/User.cpp | 6 | ||||
-rw-r--r-- | lib/VMCore/Value.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 3 |
5 files changed, 54 insertions, 30 deletions
diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 3f1a6a9..7d47044 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -308,3 +308,19 @@ BasicBlock *BasicBlock::splitBasicBlock(iterator I, const Twine &BBName) { 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); + } + } +} diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 8f4eabe..0eddd5a 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -87,11 +87,8 @@ PHINode::PHINode(const PHINode &PN) : Instruction(PN.getType(), Instruction::PHI, allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()), ReservedSpace(PN.getNumOperands()) { - 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); - } + std::copy(PN.op_begin(), PN.op_end(), op_begin()); + std::copy(PN.block_begin(), PN.block_end(), block_begin()); SubclassOptionalData = PN.SubclassOptionalData; } @@ -99,31 +96,37 @@ PHINode::~PHINode() { 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) { - unsigned NumOps = getNumOperands(); - Use *OL = OperandList; - assert(Idx*2 < NumOps && "BB not in PHI node!"); - Value *Removed = OL[Idx*2]; + Value *Removed = getIncomingValue(Idx); // Move everything after this operand down. // // FIXME: we could just swap with the end of the list, then erase. However, - // client might not expect this to happen. The code as it is thrashes the + // clients might not expect this to happen. The code as it is thrashes the // use/def lists, which is kinda lame. - for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) { - OL[i-2] = OL[i]; - OL[i-2+1] = OL[i+1]; - } + std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx); + std::copy(block_begin() + Idx + 1, block_end(), block_begin() + Idx); // Nuke the last value. - OL[NumOps-2].set(0); - OL[NumOps-2+1].set(0); - NumOperands = NumOps-2; + Op<-1>().set(0); + --NumOperands; // If the PHI node is dead, because it has zero entries, nuke it now. - if (NumOps == 2 && DeletePHIIfEmpty) { + if (getNumOperands() == 0 && DeletePHIIfEmpty) { // If anyone is using this PHI, make them use a dummy value instead... replaceAllUsesWith(UndefValue::get(getType())); eraseFromParent(); @@ -137,15 +140,18 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) { /// void PHINode::growOperands() { unsigned e = getNumOperands(); - // 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. + 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(); ReservedSpace = NumOps; - Use *OldOps = OperandList; - Use *NewOps = allocHungoffUses(NumOps); - std::copy(OldOps, OldOps + e, NewOps); - OperandList = NewOps; + OperandList = allocHungoffUses(ReservedSpace); + + std::copy(OldOps, OldOps + e, op_begin()); + std::copy(OldBlocks, OldBlocks + e, block_begin()); + Use::zap(OldOps, OldOps + e, true); } diff --git a/lib/VMCore/User.cpp b/lib/VMCore/User.cpp index 9601da7..f01fa34 100644 --- a/lib/VMCore/User.cpp +++ b/lib/VMCore/User.cpp @@ -40,8 +40,10 @@ void User::replaceUsesOfWith(Value *From, Value *To) { //===----------------------------------------------------------------------===// Use *User::allocHungoffUses(unsigned N) const { - Use *Begin = static_cast<Use*>(::operator new(sizeof(Use) * N - + sizeof(Use::UserRef))); + // 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 *End = Begin + N; (void) new(End) Use::UserRef(const_cast<User*>(this), 1); return Use::initTags(Begin, End); diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 29f6a80..a03cddc 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -305,6 +305,9 @@ void Value::uncheckedReplaceAllUsesWith(Value *New) { U.set(New); } + + if (BasicBlock *BB = dyn_cast<BasicBlock>(this)) + BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New)); } void Value::replaceAllUsesWith(Value *New) { diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index e504016..18de671 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1139,9 +1139,6 @@ void Verifier::visitPHINode(PHINode &PN) { 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. |