aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabor Greif <ggreif@gmail.com>2009-01-11 22:33:22 +0000
committerGabor Greif <ggreif@gmail.com>2009-01-11 22:33:22 +0000
commit255b26ea3529ca096313c85dcf006565c7e916f9 (patch)
tree12c5966bc59cd46bdd5e963520fb52e12e848d80
parente7886e461b1b1cea421caec6198cc700c2e8d67e (diff)
simplify CallSite helper class to not consult the Instruction's
opcode on each delegation. Instead the information is cached on construction and the cached flag used thereafter. Introduced two predicates: isCall and isInvoke. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62055 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Support/CallSite.h59
-rw-r--r--lib/VMCore/Instructions.cpp92
2 files changed, 71 insertions, 80 deletions
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 025f9da681..544c7d7761 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -14,15 +14,19 @@
// passed by value, not by reference; it should not be "new"ed or "delete"d. It
// is efficiently copyable, assignable and constructable, with cost equivalent
// to copying a pointer (notice that it has only a single data member).
+// The internal representation carries a flag which indicates which of the two
+// variants is enclosed. This allows for cheaper checks when various accessors
+// of CallSite are employed.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_CALLSITE_H
#define LLVM_SUPPORT_CALLSITE_H
-#include "llvm/Instruction.h"
-#include "llvm/BasicBlock.h"
#include "llvm/Attributes.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Instruction.h"
namespace llvm {
@@ -30,17 +34,19 @@ class CallInst;
class InvokeInst;
class CallSite {
- Instruction *I;
+ PointerIntPair<Instruction*, 1, bool> I;
public:
- CallSite() : I(0) {}
- CallSite(CallInst *CI) : I(reinterpret_cast<Instruction*>(CI)) {}
- CallSite(InvokeInst *II) : I(reinterpret_cast<Instruction*>(II)) {}
+ CallSite() : I(0, false) {}
+ CallSite(CallInst *CI) : I(reinterpret_cast<Instruction*>(CI), true) {}
+ CallSite(InvokeInst *II) : I(reinterpret_cast<Instruction*>(II), false) {}
CallSite(Instruction *C);
CallSite(const CallSite &CS) : I(CS.I) {}
CallSite &operator=(const CallSite &CS) { I = CS.I; return *this; }
- bool operator==(const CallSite &CS) const { return I == CS.I; }
- bool operator!=(const CallSite &CS) const { return I != CS.I; }
+ bool operator==(const CallSite &CS) const { return getInstruction()
+ == CS.getInstruction(); }
+ bool operator!=(const CallSite &CS) const { return getInstruction()
+ != CS.getInstruction(); }
/// CallSite::get - This static method is sort of like a constructor. It will
/// create an appropriate call site for a Call or Invoke instruction, but it
@@ -91,21 +97,31 @@ public:
/// getType - Return the type of the instruction that generated this call site
///
- const Type *getType() const { return I->getType(); }
+ const Type *getType() const { return getInstruction()->getType(); }
+
+ /// isCall - true if a CallInst is enclosed.
+ /// Note that !isCall() does not mean it is an InvokeInst enclosed,
+ /// it also could signify a NULL Instruction pointer.
+ bool isCall() const { return I.getInt(); }
+
+ /// isInvoke - true if a InvokeInst is enclosed.
+ ///
+ bool isInvoke() const { return getInstruction() && !I.getInt(); }
/// getInstruction - Return the instruction this call site corresponds to
///
- Instruction *getInstruction() const { return I; }
+ Instruction *getInstruction() const { return I.getPointer(); }
/// getCaller - Return the caller function for this call site
///
- Function *getCaller() const { return I->getParent()->getParent(); }
+ Function *getCaller() const { return getInstruction()
+ ->getParent()->getParent(); }
/// getCalledValue - Return the pointer to function that is being called...
///
Value *getCalledValue() const {
- assert(I && "Not a call or invoke instruction!");
- return I->getOperand(0);
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ return getInstruction()->getOperand(0);
}
/// getCalledFunction - Return the function being called if this is a direct
@@ -118,8 +134,8 @@ public:
/// setCalledFunction - Set the callee to the specified value...
///
void setCalledFunction(Value *V) {
- assert(I && "Not a call or invoke instruction!");
- I->setOperand(0, V);
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ getInstruction()->setOperand(0, V);
}
Value *getArgument(unsigned ArgNo) const {
@@ -128,9 +144,9 @@ public:
}
void setArgument(unsigned ArgNo, Value* newVal) {
- assert(I && "Not a call or invoke instruction!");
+ assert(getInstruction() && "Not a call or invoke instruction!");
assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
- I->setOperand(getArgumentOffset() + ArgNo, newVal);
+ getInstruction()->setOperand(getArgumentOffset() + ArgNo, newVal);
}
/// Given an operand number, returns the argument that corresponds to it.
@@ -153,11 +169,12 @@ public:
/// arg_begin/arg_end - Return iterators corresponding to the actual argument
/// list for a call site.
arg_iterator arg_begin() const {
- assert(I && "Not a call or invoke instruction!");
- return I->op_begin() + getArgumentOffset(); // Skip non-arguments
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ // Skip non-arguments
+ return getInstruction()->op_begin() + getArgumentOffset();
}
- arg_iterator arg_end() const { return I->op_end(); }
+ arg_iterator arg_end() const { return getInstruction()->op_end(); }
bool arg_empty() const { return arg_end() == arg_begin(); }
unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
@@ -168,7 +185,7 @@ public:
private:
/// Returns the operand number of the first argument
unsigned getArgumentOffset() const {
- if (I->getOpcode() == Instruction::Call)
+ if (isCall())
return 1; // Skip Function
else
return 3; // Skip Function, BB, BB
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index e2ba9b49b0..1b5cfb1501 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -25,94 +25,65 @@ using namespace llvm;
// CallSite Class
//===----------------------------------------------------------------------===//
+#define CALLSITE_DELEGATE_GETTER(METHOD) \
+ Instruction *II(getInstruction()); \
+ return isCall() \
+ ? cast<CallInst>(II)->METHOD \
+ : cast<InvokeInst>(II)->METHOD
+
+#define CALLSITE_DELEGATE_SETTER(METHOD) \
+ Instruction *II(getInstruction()); \
+ if (isCall()) \
+ cast<CallInst>(II)->METHOD; \
+ else \
+ cast<InvokeInst>(II)->METHOD
+
CallSite::CallSite(Instruction *C) {
assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
- I = C;
+ I.setPointer(C);
+ I.setInt(isa<CallInst>(C));
}
unsigned CallSite::getCallingConv() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getCallingConv();
- else
- return cast<InvokeInst>(I)->getCallingConv();
+ CALLSITE_DELEGATE_GETTER(getCallingConv());
}
void CallSite::setCallingConv(unsigned CC) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setCallingConv(CC);
- else
- cast<InvokeInst>(I)->setCallingConv(CC);
+ CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
}
const AttrListPtr &CallSite::getAttributes() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getAttributes();
- else
- return cast<InvokeInst>(I)->getAttributes();
+ CALLSITE_DELEGATE_GETTER(getAttributes());
}
void CallSite::setAttributes(const AttrListPtr &PAL) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setAttributes(PAL);
- else
- cast<InvokeInst>(I)->setAttributes(PAL);
+ CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->paramHasAttr(i, attr);
- else
- return cast<InvokeInst>(I)->paramHasAttr(i, attr);
+ CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
}
uint16_t CallSite::getParamAlignment(uint16_t i) const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->getParamAlignment(i);
- else
- return cast<InvokeInst>(I)->getParamAlignment(i);
+ CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
}
-
bool CallSite::doesNotAccessMemory() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotAccessMemory();
- else
- return cast<InvokeInst>(I)->doesNotAccessMemory();
+ CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
}
void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setDoesNotAccessMemory(doesNotAccessMemory);
- else
- cast<InvokeInst>(I)->setDoesNotAccessMemory(doesNotAccessMemory);
+ CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
}
bool CallSite::onlyReadsMemory() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->onlyReadsMemory();
- else
- return cast<InvokeInst>(I)->onlyReadsMemory();
+ CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
}
void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setOnlyReadsMemory(onlyReadsMemory);
- else
- cast<InvokeInst>(I)->setOnlyReadsMemory(onlyReadsMemory);
+ CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
}
bool CallSite::doesNotReturn() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotReturn();
- else
- return cast<InvokeInst>(I)->doesNotReturn();
+ CALLSITE_DELEGATE_GETTER(doesNotReturn());
}
void CallSite::setDoesNotReturn(bool doesNotReturn) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setDoesNotReturn(doesNotReturn);
- else
- cast<InvokeInst>(I)->setDoesNotReturn(doesNotReturn);
+ CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
}
bool CallSite::doesNotThrow() const {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- return CI->doesNotThrow();
- else
- return cast<InvokeInst>(I)->doesNotThrow();
+ CALLSITE_DELEGATE_GETTER(doesNotThrow());
}
void CallSite::setDoesNotThrow(bool doesNotThrow) {
- if (CallInst *CI = dyn_cast<CallInst>(I))
- CI->setDoesNotThrow(doesNotThrow);
- else
- cast<InvokeInst>(I)->setDoesNotThrow(doesNotThrow);
+ CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
}
bool CallSite::hasArgument(const Value *Arg) const {
@@ -122,6 +93,9 @@ bool CallSite::hasArgument(const Value *Arg) const {
return false;
}
+#undef CALLSITE_DELEGATE_GETTER
+#undef CALLSITE_DELEGATE_SETTER
+
//===----------------------------------------------------------------------===//
// TerminatorInst Class
//===----------------------------------------------------------------------===//
@@ -1442,7 +1416,7 @@ InsertValueInst::InsertValueInst(Value *Agg,
//===----------------------------------------------------------------------===//
void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx,
- const std::string &Name) {
+ const std::string &Name) {
assert(NumOperands == 1 && "NumOperands not initialized?");
Indices.insert(Indices.end(), Idx, Idx + NumIdx);