aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorGabor Greif <ggreif@gmail.com>2009-03-12 18:34:49 +0000
committerGabor Greif <ggreif@gmail.com>2009-03-12 18:34:49 +0000
commitae5a20a9177650525b40ed88c8326a398e6caa8a (patch)
treea9a55d209febc8db93b45efd3be22850d744366b /lib/VMCore
parenta065200eaf71248133470caf03eefea449fff7b4 (diff)
downloadexternal_llvm-ae5a20a9177650525b40ed88c8326a398e6caa8a.zip
external_llvm-ae5a20a9177650525b40ed88c8326a398e6caa8a.tar.gz
external_llvm-ae5a20a9177650525b40ed88c8326a398e6caa8a.tar.bz2
Rearrange operands of the BranchInst, to be able to
access each with a fixed negative index from op_end(). This has two important implications: - getUser() will work faster, because there are less iterations for the waymarking algorithm to perform. This is important when running various analyses that want to determine callers of basic blocks. - getSuccessor() now runs faster, because the indirection via OperandList is not necessary: Uses corresponding to the successors are at fixed offset to "this". The price we pay is the slightly more complicated logic in the operator User::delete, as it has to pick up the information whether it has to free the memory of an original unconditional BranchInst or a BranchInst that was originally conditional, but has been shortened to unconditional. I was not able to come up with a nicer solution to this problem. (And rest assured, I tried *a lot*). Similar reorderings will follow for InvokeInst and CallInst. After that some optimizations to pred_iterator and CallSite will fall out naturally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66815 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Instructions.cpp50
-rw-r--r--lib/VMCore/Use.cpp67
-rw-r--r--lib/VMCore/Value.cpp18
3 files changed, 105 insertions, 30 deletions
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 7f5d461..fe30271 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -612,16 +612,16 @@ BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore)
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertBefore) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Op<0>() = IfTrue;
+ Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
Instruction *InsertBefore)
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertBefore) {
- Op<0>() = IfTrue;
- Op<1>() = IfFalse;
- Op<2>() = Cond;
+ Op<-1>() = IfTrue;
+ Op<-2>() = IfFalse;
+ Op<-3>() = Cond;
#ifndef NDEBUG
AssertOK();
#endif
@@ -632,7 +632,7 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd)
OperandTraits<BranchInst>::op_end(this) - 1,
1, InsertAtEnd) {
assert(IfTrue != 0 && "Branch destination may not be null!");
- Op<0>() = IfTrue;
+ Op<-1>() = IfTrue;
}
BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
@@ -640,9 +640,9 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
: TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - 3,
3, InsertAtEnd) {
- Op<0>() = IfTrue;
- Op<1>() = IfFalse;
- Op<2>() = Cond;
+ Op<-1>() = IfTrue;
+ Op<-2>() = IfFalse;
+ Op<-3>() = Cond;
#ifndef NDEBUG
AssertOK();
#endif
@@ -653,14 +653,39 @@ BranchInst::BranchInst(const BranchInst &BI) :
TerminatorInst(Type::VoidTy, Instruction::Br,
OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
BI.getNumOperands()) {
- OperandList[0] = BI.getOperand(0);
+ Op<-1>() = BI.Op<-1>();
if (BI.getNumOperands() != 1) {
assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
- OperandList[1] = BI.getOperand(1);
- OperandList[2] = BI.getOperand(2);
+ Op<-3>() = BI.Op<-3>();
+ Op<-2>() = BI.Op<-2>();
}
}
+
+Use* Use::getPrefix() {
+ PointerIntPair<Use**, 2, PrevPtrTag> &PotentialPrefix(this[-1].Prev);
+ if (PotentialPrefix.getOpaqueValue())
+ return 0;
+
+ return reinterpret_cast<Use*>((char*)&PotentialPrefix + 1);
+}
+
+BranchInst::~BranchInst() {
+ if (NumOperands == 1) {
+ if (Use *Prefix = OperandList->getPrefix()) {
+ Op<-1>() = 0;
+ //
+ // mark OperandList to have a special value for scrutiny
+ // by baseclass destructors and operator delete
+ OperandList = Prefix;
+ } else {
+ NumOperands = 3;
+ OperandList = op_begin();
+ }
+ }
+}
+
+
BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {
return getSuccessor(idx);
}
@@ -2927,7 +2952,8 @@ ReturnInst *ReturnInst::clone() const {
return new(getNumOperands()) ReturnInst(*this);
}
BranchInst *BranchInst::clone() const {
- return new(getNumOperands()) BranchInst(*this);
+ unsigned Ops(getNumOperands());
+ return new(Ops, Ops == 1) BranchInst(*this);
}
SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
InvokeInst *InvokeInst::clone() const {
diff --git a/lib/VMCore/Use.cpp b/lib/VMCore/Use.cpp
index 0c566a9..b25415a 100644
--- a/lib/VMCore/Use.cpp
+++ b/lib/VMCore/Use.cpp
@@ -163,4 +163,71 @@ Use *User::allocHungoffUses(unsigned N) const {
return Use::initTags(Begin, End);
}
+//===----------------------------------------------------------------------===//
+// User operator new Implementations
+//===----------------------------------------------------------------------===//
+
+void *User::operator new(size_t s, unsigned Us) {
+ void *Storage = ::operator new(s + sizeof(Use) * Us);
+ Use *Start = static_cast<Use*>(Storage);
+ Use *End = Start + Us;
+ User *Obj = reinterpret_cast<User*>(End);
+ Obj->OperandList = Start;
+ Obj->NumOperands = Us;
+ Use::initTags(Start, End);
+ return Obj;
+}
+
+/// Prefixed allocation - just before the first Use, allocate a NULL pointer.
+/// The destructor can detect its presence and readjust the OperandList
+/// for deletition.
+///
+void *User::operator new(size_t s, unsigned Us, bool Prefix) {
+ // currently prefixed allocation only admissible for
+ // unconditional branch instructions
+ if (!Prefix)
+ return operator new(s, Us);
+
+ assert(Us == 1 && "Other than one Use allocated?");
+ typedef PointerIntPair<void*, 2, Use::PrevPtrTag> TaggedPrefix;
+ void *Raw = ::operator new(s + sizeof(TaggedPrefix) + sizeof(Use) * Us);
+ TaggedPrefix *Pre = static_cast<TaggedPrefix*>(Raw);
+ Pre->setFromOpaqueValue(0);
+ void *Storage = Pre + 1; // skip over prefix
+ Use *Start = static_cast<Use*>(Storage);
+ Use *End = Start + Us;
+ User *Obj = reinterpret_cast<User*>(End);
+ Obj->OperandList = Start;
+ Obj->NumOperands = Us;
+ Use::initTags(Start, End);
+ return Obj;
+}
+
+//===----------------------------------------------------------------------===//
+// User operator delete Implementation
+//===----------------------------------------------------------------------===//
+
+void User::operator delete(void *Usr) {
+ User *Start = static_cast<User*>(Usr);
+ Use *Storage = static_cast<Use*>(Usr) - Start->NumOperands;
+ //
+ // look for a variadic User
+ if (Storage == Start->OperandList) {
+ ::operator delete(Storage);
+ return;
+ }
+ //
+ // check for the flag whether the destructor has detected a prefixed
+ // allocation, in which case we remove the flag and delete starting
+ // at OperandList
+ if (reinterpret_cast<intptr_t>(Start->OperandList) & 1) {
+ ::operator delete(reinterpret_cast<char*>(Start->OperandList) - 1);
+ return;
+ }
+ //
+ // in all other cases just delete the nullary User (covers hung-off
+ // uses also
+ ::operator delete(Usr);
+}
+
} // End llvm namespace
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index ab7e044..0aa2db4 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -406,21 +406,3 @@ void User::replaceUsesOfWith(Value *From, Value *To) {
}
}
-void *User::operator new(size_t s, unsigned Us) {
- void *Storage = ::operator new(s + sizeof(Use) * Us);
- Use *Start = static_cast<Use*>(Storage);
- Use *End = Start + Us;
- User *Obj = reinterpret_cast<User*>(End);
- Obj->OperandList = Start;
- Obj->NumOperands = Us;
- Use::initTags(Start, End);
- return Obj;
-}
-
-void User::operator delete(void *Usr) {
- User *Start = static_cast<User*>(Usr);
- Use *Storage = static_cast<Use*>(Usr) - Start->NumOperands;
- ::operator delete(Storage == Start->OperandList
- ? Storage
- : Usr);
-}