diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index 025f9da6819..544c7d7761b 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 I; public: - CallSite() : I(0) {} - CallSite(CallInst *CI) : I(reinterpret_cast(CI)) {} - CallSite(InvokeInst *II) : I(reinterpret_cast(II)) {} + CallSite() : I(0, false) {} + CallSite(CallInst *CI) : I(reinterpret_cast(CI), true) {} + CallSite(InvokeInst *II) : I(reinterpret_cast(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 e2ba9b49b05..1b5cfb15013 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(II)->METHOD \ + : cast(II)->METHOD + +#define CALLSITE_DELEGATE_SETTER(METHOD) \ + Instruction *II(getInstruction()); \ + if (isCall()) \ + cast(II)->METHOD; \ + else \ + cast(II)->METHOD + CallSite::CallSite(Instruction *C) { assert((isa(C) || isa(C)) && "Not a call!"); - I = C; + I.setPointer(C); + I.setInt(isa(C)); } unsigned CallSite::getCallingConv() const { - if (CallInst *CI = dyn_cast(I)) - return CI->getCallingConv(); - else - return cast(I)->getCallingConv(); + CALLSITE_DELEGATE_GETTER(getCallingConv()); } void CallSite::setCallingConv(unsigned CC) { - if (CallInst *CI = dyn_cast(I)) - CI->setCallingConv(CC); - else - cast(I)->setCallingConv(CC); + CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); } const AttrListPtr &CallSite::getAttributes() const { - if (CallInst *CI = dyn_cast(I)) - return CI->getAttributes(); - else - return cast(I)->getAttributes(); + CALLSITE_DELEGATE_GETTER(getAttributes()); } void CallSite::setAttributes(const AttrListPtr &PAL) { - if (CallInst *CI = dyn_cast(I)) - CI->setAttributes(PAL); - else - cast(I)->setAttributes(PAL); + CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); } bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const { - if (CallInst *CI = dyn_cast(I)) - return CI->paramHasAttr(i, attr); - else - return cast(I)->paramHasAttr(i, attr); + CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr)); } uint16_t CallSite::getParamAlignment(uint16_t i) const { - if (CallInst *CI = dyn_cast(I)) - return CI->getParamAlignment(i); - else - return cast(I)->getParamAlignment(i); + CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); } - bool CallSite::doesNotAccessMemory() const { - if (CallInst *CI = dyn_cast(I)) - return CI->doesNotAccessMemory(); - else - return cast(I)->doesNotAccessMemory(); + CALLSITE_DELEGATE_GETTER(doesNotAccessMemory()); } void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) { - if (CallInst *CI = dyn_cast(I)) - CI->setDoesNotAccessMemory(doesNotAccessMemory); - else - cast(I)->setDoesNotAccessMemory(doesNotAccessMemory); + CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory)); } bool CallSite::onlyReadsMemory() const { - if (CallInst *CI = dyn_cast(I)) - return CI->onlyReadsMemory(); - else - return cast(I)->onlyReadsMemory(); + CALLSITE_DELEGATE_GETTER(onlyReadsMemory()); } void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) { - if (CallInst *CI = dyn_cast(I)) - CI->setOnlyReadsMemory(onlyReadsMemory); - else - cast(I)->setOnlyReadsMemory(onlyReadsMemory); + CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory)); } bool CallSite::doesNotReturn() const { - if (CallInst *CI = dyn_cast(I)) - return CI->doesNotReturn(); - else - return cast(I)->doesNotReturn(); + CALLSITE_DELEGATE_GETTER(doesNotReturn()); } void CallSite::setDoesNotReturn(bool doesNotReturn) { - if (CallInst *CI = dyn_cast(I)) - CI->setDoesNotReturn(doesNotReturn); - else - cast(I)->setDoesNotReturn(doesNotReturn); + CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn)); } bool CallSite::doesNotThrow() const { - if (CallInst *CI = dyn_cast(I)) - return CI->doesNotThrow(); - else - return cast(I)->doesNotThrow(); + CALLSITE_DELEGATE_GETTER(doesNotThrow()); } void CallSite::setDoesNotThrow(bool doesNotThrow) { - if (CallInst *CI = dyn_cast(I)) - CI->setDoesNotThrow(doesNotThrow); - else - cast(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);