// will be set for a value after reg allocation
private:
MachineOperand()
- : immedVal(0), opType(MO_VirtualRegister), flags(0), regNum(-1) {}
+ : immedVal(0),
+ opType(MO_VirtualRegister),
+ flags(0),
+ regNum(-1) {}
+
MachineOperand(int64_t ImmVal, MachineOperandType OpTy)
- : immedVal(ImmVal), opType(OpTy), flags(0), regNum(-1) {}
+ : immedVal(ImmVal),
+ opType(OpTy),
+ flags(0),
+ regNum(-1) {}
+
MachineOperand(int Reg, MachineOperandType OpTy, bool isDef = false)
- : immedVal(0), opType(OpTy), flags(isDef ? DEFFLAG : 0), regNum(Reg) {}
+ : immedVal(0),
+ opType(OpTy),
+ flags(isDef ? DEFFLAG : 0),
+ regNum(Reg) {}
+
MachineOperand(Value *V, MachineOperandType OpTy,
bool isDef = false, bool isDNU = false)
- : value(V), opType(OpTy), regNum(-1) {
+ : value(V),
+ opType(OpTy),
+ regNum(-1) {
flags = (isDef ? DEFFLAG : 0) | (isDNU ? DEFUSEFLAG : 0);
}
public:
MachineOperand(const MachineOperand &M)
- : immedVal(M.immedVal), opType(M.opType), flags(M.flags), regNum(M.regNum) {
- }
+ : immedVal(M.immedVal),
+ opType(M.opType),
+ flags(M.flags),
+ regNum(M.regNum) {}
+
~MachineOperand() {}
// Accessor methods. Caller is responsible for checking the
// a CALL (if any), and return value of a RETURN.
//---------------------------------------------------------------------------
-class MachineInstr : public Annotable, // MachineInstrs are annotable
- public NonCopyable { // Disable copy operations
+class MachineInstr: public NonCopyable { // Disable copy operations
+
MachineOpCode opCode; // the opcode
std::vector<MachineOperand> operands; // the operands
+ unsigned numImplicitRefs; // number of implicit operands
- struct ImplicitRef {
- Value *Val;
- bool isDef, isDefAndUse;
-
- ImplicitRef(Value *V, bool D, bool DU) : Val(V), isDef(D), isDefAndUse(DU){}
- };
-
- // implicitRefs - Values implicitly referenced by this machine instruction
- // (eg, call args)
- std::vector<ImplicitRef> implicitRefs;
+ MachineOperand& getImplicitOp(unsigned i) {
+ assert(i < numImplicitRefs && "implicit ref# out of range!");
+ return operands[i + operands.size() - numImplicitRefs];
+ }
+ const MachineOperand& getImplicitOp(unsigned i) const {
+ assert(i < numImplicitRefs && "implicit ref# out of range!");
+ return operands[i + operands.size() - numImplicitRefs];
+ }
// regsUsed - all machine registers used for this instruction, including regs
// used to save values across the instruction. This is a bitset of registers.
// OperandComplete - Return true if it's illegal to add a new operand
bool OperandsComplete() const;
+
public:
MachineInstr(MachineOpCode Opcode);
MachineInstr(MachineOpCode Opcode, unsigned numOperands);
//
// Information about explicit operands of the instruction
//
- unsigned getNumOperands() const { return operands.size(); }
+ unsigned getNumOperands() const { return operands.size() - numImplicitRefs; }
const MachineOperand& getOperand(unsigned i) const {
- assert(i < operands.size() && "getOperand() out of range!");
+ assert(i < getNumOperands() && "getOperand() out of range!");
return operands[i];
}
MachineOperand& getOperand(unsigned i) {
- assert(i < operands.size() && "getOperand() out of range!");
+ assert(i < getNumOperands() && "getOperand() out of range!");
return operands[i];
}
bool operandIsDefinedAndUsed(unsigned i) const {
return getOperand(i).opIsDefAndUse();
}
-
+
//
// Information about implicit operands of the instruction
//
- unsigned getNumImplicitRefs() const{ return implicitRefs.size();}
+ unsigned getNumImplicitRefs() const{ return numImplicitRefs; }
const Value* getImplicitRef(unsigned i) const {
- assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
- return implicitRefs[i].Val;
+ return getImplicitOp(i).getVRegValue();
}
Value* getImplicitRef(unsigned i) {
- assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
- return implicitRefs[i].Val;
+ return getImplicitOp(i).getVRegValue();
}
bool implicitRefIsDefined(unsigned i) const {
- assert(i < implicitRefs.size() && "implicitRefIsDefined() out of range!");
- return implicitRefs[i].isDef;
+ return getImplicitOp(i).opIsDef();
}
bool implicitRefIsDefinedAndUsed(unsigned i) const {
- assert(i < implicitRefs.size() && "implicitRefIsDef&Used() out of range!");
- return implicitRefs[i].isDefAndUse;
+ return getImplicitOp(i).opIsDefAndUse();
}
-
- void addImplicitRef(Value* V, bool isDef=false, bool isDefAndUse=false) {
- implicitRefs.push_back(ImplicitRef(V, isDef, isDefAndUse));
- }
-
- void setImplicitRef(unsigned i, Value* V, bool isDef=false,
- bool isDefAndUse=false) {
- assert(i < implicitRefs.size() && "setImplicitRef() out of range!");
- implicitRefs[i] = ImplicitRef(V, isDef, isDefAndUse);
- }
-
+ inline void addImplicitRef (Value* V,
+ bool isDef=false,bool isDefAndUse=false);
+ inline void setImplicitRef (unsigned i, Value* V,
+ bool isDef=false, bool isDefAndUse=false);
+
//
// Information about registers used in this instruction
//
//
// Define iterators to access the Value operands of the Machine Instruction.
+ // Note that these iterators only enumerate the explicit operands.
// begin() and end() are defined to produce these iterators...
//
template<class _MI, class _V> class ValOpIterator;
typedef ValOpIterator<const MachineInstr*,const Value*> const_val_op_iterator;
typedef ValOpIterator< MachineInstr*, Value*> val_op_iterator;
-
// Access to set the operands when building the machine instruction
//
- void SetMachineOperandVal(unsigned i,
- MachineOperand::MachineOperandType operandType,
- Value* V, bool isDef=false, bool isDefAndUse=false);
- void SetMachineOperandConst(unsigned i,
- MachineOperand::MachineOperandType operandType,
- int64_t intValue);
- void SetMachineOperandReg(unsigned i, int regNum, bool isDef=false);
+ void SetMachineOperandVal (unsigned i,
+ MachineOperand::MachineOperandType operandType,
+ Value* V,
+ bool isDef=false,
+ bool isDefAndUse=false);
+
+ void SetMachineOperandConst (unsigned i,
+ MachineOperand::MachineOperandType operandType,
+ int64_t intValue);
+
+ void SetMachineOperandReg (unsigned i,
+ int regNum,
+ bool isDef=false);
//===--------------------------------------------------------------------===//
// Accessors to add operands when building up machine instructions
void skipToNextVal() {
while (i < MI->getNumOperands() &&
- !((MI->getOperandType(i) == MachineOperand::MO_VirtualRegister ||
- MI->getOperandType(i) == MachineOperand::MO_CCRegister)
- && MI->getOperand(i).getVRegValue() != 0))
+ !( (MI->getOperandType(i) == MachineOperand::MO_VirtualRegister ||
+ MI->getOperandType(i) == MachineOperand::MO_CCRegister)
+ && MI->getOperand(i).getVRegValue() != 0))
++i;
}
}
};
+
+// Define here to enable inlining of the functions used.
+//
+void MachineInstr::addImplicitRef(Value* V,
+ bool isDef,
+ bool isDefAndUse)
+{
+ ++numImplicitRefs;
+ addRegOperand(V, isDef, isDefAndUse);
+}
+
+void MachineInstr::setImplicitRef(unsigned i,
+ Value* V,
+ bool isDef,
+ bool isDefAndUse)
+{
+ assert(i < getNumImplicitRefs() && "setImplicitRef() out of range!");
+ SetMachineOperandVal(i + getNumImplicitRefs(),
+ MachineOperand::MO_VirtualRegister,
+ V, isDef, isDefAndUse);
+}
+
+
//---------------------------------------------------------------------------
// Debugging Support
//---------------------------------------------------------------------------
-std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
+std::ostream& operator<< (std::ostream& os,
+ const MachineInstr& minstr);
-std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
+std::ostream& operator<< (std::ostream& os,
+ const MachineOperand& mop);
-void PrintMachineInstructions(const Function *F);
+void PrintMachineInstructions (const Function *F);
#endif
// Constructor for instructions with fixed #operands (nearly all)
MachineInstr::MachineInstr(MachineOpCode _opCode)
: opCode(_opCode),
- operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()) {
+ operands(TargetInstrDescriptors[_opCode].numOperands, MachineOperand()),
+ numImplicitRefs(0)
+{
assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
}
// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned numOperands)
- : opCode(OpCode), operands(numOperands, MachineOperand()) {
+ : opCode(OpCode),
+ operands(numOperands, MachineOperand()),
+ numImplicitRefs(0)
+{
}
MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands,
- bool XX, bool YY) : opCode(Opcode) {
+ bool XX, bool YY)
+ : opCode(Opcode),
+ numImplicitRefs(0)
+{
operands.reserve(numOperands);
}
// OperandComplete - Return true if it's illegal to add a new operand
-bool MachineInstr::OperandsComplete() const {
+bool MachineInstr::OperandsComplete() const
+{
int NumOperands = TargetInstrDescriptors[opCode].numOperands;
- if (NumOperands >= 0 && operands.size() >= (unsigned)NumOperands)
+ if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
return true; // Broken!
return false;
}
// This only resets the size of the operand vector and initializes it.
// The new operands must be set explicitly later.
//
-void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands) {
+void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands)
+{
+ assert(getNumImplicitRefs() == 0 &&
+ "This is probably broken because implicit refs are going to be lost.");
opCode = Opcode;
operands.clear();
operands.resize(numOperands, MachineOperand());
bool isdef,
bool isDefAndUse)
{
- assert(i < operands.size());
+ assert(i < operands.size()); // may be explicit or implicit op
operands[i].opType = opType;
operands[i].value = V;
operands[i].regNum = -1;
MachineOperand::MachineOperandType operandType,
int64_t intValue)
{
- assert(i < operands.size());
+ assert(i < getNumOperands()); // must be explicit op
assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
"immed. constant cannot be defined");
MachineInstr::SetMachineOperandReg(unsigned i,
int regNum,
bool isdef) {
- assert(i < operands.size());
+ assert(i < getNumOperands()); // must be explicit op
operands[i].opType = MachineOperand::MO_MachineRegister;
operands[i].value = NULL;
void
MachineInstr::SetRegForOperand(unsigned i, int regNum)
{
+ assert(i < getNumOperands()); // must be explicit op
operands[i].setRegForValue(regNum);
insertUsedReg(regNum);
}
}
// Subsitute implicit refs
- for (unsigned i=0, N=implicitRefs.size(); i < N; ++i)
+ for (unsigned i=0, N=getNumImplicitRefs(); i < N; ++i)
if (getImplicitRef(i) == oldVal)
if (!defsOnly || implicitRefIsDefined(i))
{
- implicitRefs[i].Val = newVal;
+ getImplicitOp(i).value = newVal;
++numSubst;
}
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineInstrAnnot.h"
-#include "llvm/Annotation.h"
+#include "llvm/CodeGen/InstrSelection.h"
+#include "llvm/CodeGen/InstrSelectionSupport.h"
+#include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/iOther.h"
#include "llvm/Type.h"
-AnnotationID CallArgsDescriptor::AID(AnnotationManager::
- getID("CodeGen::CallArgsDescriptor"));
CallArgsDescriptor::CallArgsDescriptor(const CallInst* _callInstr,
TmpInstruction* _retAddrReg,
bool _isVarArgs, bool _noPrototype)
- : Annotation(AID),
- callInstr(_callInstr),
+ : callInstr(_callInstr),
funcPtr(isa<Function>(_callInstr->getCalledValue())
? NULL : _callInstr->getCalledValue()),
retAddrReg(_retAddrReg),
&& "Operand 0 is ignored in the loop below!");
for (unsigned int i=1; i < numArgs; ++i)
argInfoVec.push_back(CallArgInfo(callInstr->getOperand(i)));
+
+ // Enter this object in the MachineCodeForInstr object of the CallInst.
+ // This transfers ownership of this object.
+ MachineCodeForInstruction::get(callInstr).setCallArgsDescriptor(this);
}
{
return (callInstr->getType() == Type::VoidTy? NULL : callInstr);
}
+
+
+// Mechanism to get the descriptor for a CALL MachineInstr.
+// We get the LLVM CallInstr from the ret. addr. register argument
+// of the CALL MachineInstr, then get the CallArgsDescriptor from the
+// MachineCodeForInstruction object for the CallInstr.
+// This is roundabout but avoids adding a new map or annotation just
+// to keep track of CallArgsDescriptors.
+//
+CallArgsDescriptor *CallArgsDescriptor::get(const MachineInstr* MI)
+{
+ const TmpInstruction* retAddrReg =
+ cast<TmpInstruction>(MI->getImplicitRef(MI->getNumImplicitRefs()-1));
+ assert(retAddrReg->getNumOperands() == 1 &&
+ isa<CallInst>(retAddrReg->getOperand(0)) &&
+ "Order of implicit args of CALL instr. changed. FIX THIS CODE!");
+ const CallInst* callInstr = cast<CallInst>(retAddrReg->getOperand(0));
+
+ CallArgsDescriptor* desc =
+ MachineCodeForInstruction::get(callInstr).getCallArgsDescriptor();
+ assert(desc->getCallInst()==callInstr && "Incorrect call args descriptor?");
+ return desc;
+}