From a995e6086deca9cbd9aab9d6e1e94b36964b66da Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Thu, 11 Oct 2001 04:23:19 +0000 Subject: [PATCH] Record implicitRefs for each machine instruction instead of each VM instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@725 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineInstr.h | 116 +++++++++++++------ lib/Target/SparcV9/SparcV9InstrSelection.cpp | 71 +++++------- 2 files changed, 115 insertions(+), 72 deletions(-) diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index a679590851f..0efd8abb79c 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -234,13 +234,23 @@ MachineOperand::InitializeReg(unsigned int _regNum) // PREDICT-NOT-TAKEN: if 1: predict branch not taken. // Instead of creating 4 different opcodes for BNZ, we create a single // opcode and set bits in opCodeMask for each of these flags. +// +// There are 2 kinds of operands: +// +// (1) Explicit operands of the machine instruction in vector operands[] +// +// (2) "Implicit operands" are values implicitly used or defined by the +// machine instruction, such as arguments to a CALL, return value of +// a CALL (if any), and return value of a RETURN. //--------------------------------------------------------------------------- class MachineInstr : public NonCopyable { private: - MachineOpCode opCode; - OpCodeMask opCodeMask; // extra bits for variants of an opcode + MachineOpCode opCode; + OpCodeMask opCodeMask; // extra bits for variants of an opcode vector operands; + vector implicitRefs; // values implicitly referenced by this + vector implicitIsDef; // machine instruction (eg, call args) public: typedef ValOpIterator val_op_const_iterator; @@ -254,20 +264,33 @@ public: OpCodeMask _opCodeMask = 0x0); inline ~MachineInstr () {} - const MachineOpCode getOpCode () const; + const MachineOpCode getOpCode () const { return opCode; } - unsigned int getNumOperands () const; + // + // Information about explicit operands of the instruction + // + unsigned int getNumOperands () const { return operands.size(); } + + bool operandIsDefined(unsigned int i) const; const MachineOperand& getOperand (unsigned int i) const; MachineOperand& getOperand (unsigned int i); - bool operandIsDefined(unsigned int i) const; + // + // Information about implicit operands of the instruction + // + unsigned int getNumImplicitRefs() const{return implicitRefs.size();} + + bool implicitRefIsDefined(unsigned int i) const; + const Value* getImplicitRef (unsigned int i) const; + Value* getImplicitRef (unsigned int i); + + // + // Debugging support + // void dump (unsigned int indent = 0) const; - - - public: friend ostream& operator<<(ostream& os, const MachineInstr& minstr); @@ -285,19 +308,15 @@ public: void SetMachineOperand(unsigned int i, unsigned int regNum, bool isDef=false); -}; -inline const MachineOpCode -MachineInstr::getOpCode() const -{ - return opCode; -} + void addImplicitRef (Value* val, + bool isDef=false); + + void setImplicitRef (unsigned int i, + Value* val, + bool isDef=false); +}; -inline unsigned int -MachineInstr::getNumOperands() const -{ - return operands.size(); -} inline MachineOperand& MachineInstr::getOperand(unsigned int i) @@ -319,6 +338,45 @@ MachineInstr::operandIsDefined(unsigned int i) const return getOperand(i).opIsDef(); } +inline bool +MachineInstr::implicitRefIsDefined(unsigned int i) const +{ + assert(i < implicitIsDef.size() && "operand out of range!"); + return implicitIsDef[i]; +} + +inline const Value* +MachineInstr::getImplicitRef(unsigned int i) const +{ + assert(i < implicitRefs.size() && "getImplicitRef() out of range!"); + return implicitRefs[i]; +} + +inline Value* +MachineInstr::getImplicitRef(unsigned int i) +{ + assert(i < implicitRefs.size() && "getImplicitRef() out of range!"); + return implicitRefs[i]; +} + +inline void +MachineInstr::addImplicitRef(Value* val, + bool isDef) +{ + implicitRefs.push_back(val); + implicitIsDef.push_back(isDef); +} + +inline void +MachineInstr::setImplicitRef(unsigned int i, + Value* val, + bool isDef) +{ + assert(i < implicitRefs.size() && "setImplicitRef() out of range!"); + implicitRefs[i] = val; + implicitIsDef[i] = isDef; +} + template class ValOpIterator : public std::forward_iterator<_V, ptrdiff_t> { @@ -364,16 +422,13 @@ public: // Purpose: // Representation of the sequence of machine instructions created // for a single VM instruction. Additionally records information -// about hidden and implicit values used by the machine instructions: +// about hidden values used by the machine instructions: // -// (1) "Temporary values" are intermediate values used in the machine -// instruction sequence, but not in the VM instruction -// Note that such values should be treated as pure SSA values with -// no interpretation of their operands (i.e., as a TmpInstruction -// object which actually represents such a value). -// -// (2) "Implicit uses" are values used in the VM instruction but not in -// the machine instruction sequence +// "Temporary values" are intermediate values used in the machine +// instruction sequence, but not in the VM instruction +// Note that such values should be treated as pure SSA values with +// no interpretation of their operands (i.e., as a TmpInstruction +// object which actually represents such a value). // //--------------------------------------------------------------------------- @@ -381,7 +436,6 @@ class MachineCodeForVMInstr: public vector { private: vector tempVec; // used by m/c instr but not VM instr - vector implicitUses; // used by VM instr but not m/c instr public: /*ctor*/ MachineCodeForVMInstr () {} @@ -390,11 +444,7 @@ public: const vector& getTempValues () const { return tempVec; } vector& getTempValues () { return tempVec; } - const vector& getImplicitUses() const { return implicitUses; } - vector& getImplicitUses() { return implicitUses; } - void addTempValue (Value* val) { tempVec.push_back(val); } - void addImplicitUse(Value* val) { implicitUses.push_back(val);} // dropAllReferences() - This function drops all references within // temporary (hidden) instructions created in implementing the original diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp index 48a038d6828..6f8edf57246 100644 --- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp +++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp @@ -1233,33 +1233,24 @@ FixConstantOperands(const InstructionNode* vmInstrNode, minstr->SetMachineOperand(op, opType, immedValue); } } - } - - // - // Also, check for operands of the VM instruction that are implicit - // operands of the machine instruction. These include: - // -- arguments to a Call - // -- return value of a Return - // - // Any such operand that is a constant value needs to be fixed also. - // At least these instructions with implicit uses (viz., Call and Return) - // have no immediate fields, so the constant needs to be loaded into - // a register. - // - vector& implUseVec = vmInstr->getMachineInstrVec().getImplicitUses(); - if (implUseVec.size() > 0) - { - assert((vmInstr->getOpcode() == Instruction::Call || - vmInstr->getOpcode() == Instruction::Ret) - && "May need to check immediate fields for other instructions"); - for (unsigned i=1, N=implUseVec.size(); i < N; ++i) - if (isa(implUseVec[i])) + // + // Also, check for implicit operands used (not those defined) by the + // machine instruction. These include: + // -- arguments to a Call + // -- return value of a Return + // Any such operand that is a constant value needs to be fixed also. + // The current instructions with implicit refs (viz., Call and Return) + // have no immediate fields, so the constant always needs to be loaded + // into a register. + // + for (unsigned i=1, N=minstr->getNumImplicitRefs(); i < N; ++i) + if (isa(minstr->getImplicitRef(i))) { - TmpInstruction* tmpReg = - InsertCodeToLoadConstant((ConstPoolVal*) implUseVec[i], - vmInstr, loadConstVec, target); - implUseVec[i] = tmpReg; + TmpInstruction* tmpReg = InsertCodeToLoadConstant((ConstPoolVal*) + minstr->getImplicitRef(i), + vmInstr, loadConstVec, target); + minstr->setImplicitRef(i, tmpReg); } } @@ -1452,7 +1443,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, // NOTE: Prepass of register allocation is responsible // for moving return value to appropriate register. // Mark the return-address register as a hidden virtual reg. - // Mark the return value register as an implicit use. + // Mark the return value register as an implicit ref of + // the machine instruction. { ReturnInst* returnInstr = (ReturnInst*) subtreeRoot->getInstruction(); assert(returnInstr->getOpcode() == Instruction::Ret); @@ -1461,15 +1453,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, returnInstr, NULL); returnInstr->getMachineInstrVec().addTempValue(returnReg); - if (returnInstr->getReturnValue() != NULL) - returnInstr->getMachineInstrVec().addImplicitUse( - returnInstr->getReturnValue()); - mvec[0] = new MachineInstr(RETURN); mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, returnReg); mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,s8); + if (returnInstr->getReturnValue() != NULL) + mvec[0]->addImplicitRef(returnInstr->getReturnValue()); + returnReg->addMachineInstruction(mvec[0]); mvec[numInstr++] = new MachineInstr(NOP); // delay slot @@ -2055,8 +2046,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, // is available, replace this with a CALL instruction. // Mark both the indirection register and the return-address // register as hidden virtual registers. - // Also, mark the operands of the Call and the return value - // as implicit operands of the machine instruction. + // Also, mark the operands of the Call and return value (if + // any) as implicit operands of the CALL machine instruction. { CallInst *callInstr = cast(subtreeRoot->getInstruction()); Method* callee = callInstr->getCalledMethod(); @@ -2066,7 +2057,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, Instruction* retAddrReg = new TmpInstruction(Instruction::UserOp1, callInstr, NULL); - // Note temporary values and implicit uses in mvec + // Note temporary values in the machineInstrVec for the VM instr. // // WARNING: Operands 0..N-1 must go in slots 0..N-1 of implicitUses. // The result value must go in slot N. This is assumed @@ -2074,12 +2065,6 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, // callInstr->getMachineInstrVec().addTempValue(jmpAddrReg); callInstr->getMachineInstrVec().addTempValue(retAddrReg); - for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i) - if (callInstr->getOperand(i) != callee) - callInstr->getMachineInstrVec().addImplicitUse( - callInstr->getOperand(i)); - if (callInstr->getCalledMethod()->getReturnType() == Type::VoidTy) - callInstr->getMachineInstrVec().addImplicitUse(callInstr); // Generate the machine instruction and its operands mvec[0] = new MachineInstr(JMPL); @@ -2090,6 +2075,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot, mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, retAddrReg); + // Add the call operands and return value as implicit refs + for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i) + if (callInstr->getOperand(i) != callee) + mvec[0]->addImplicitRef(callInstr->getOperand(i)); + + if (callInstr->getCalledMethod()->getReturnType() != Type::VoidTy) + mvec[0]->addImplicitRef(callInstr, /*isDef*/ true); + // NOTE: jmpAddrReg will be loaded by a different instruction generated // by the final code generator, so we just mark the CALL instruction // as computing that value. -- 2.34.1