Make MachineOperand's value named 'contents'. Make really, really sure

it is always completely initialized and copied.
Also, fix up many comments and asserts.

llvm-svn: 12100
This commit is contained in:
Brian Gaeke 2004-03-03 19:07:27 +00:00
parent 3001c6e264
commit 015972103d
2 changed files with 105 additions and 70 deletions

View File

@ -121,60 +121,69 @@ private:
MachineBasicBlock *MBB; // For MO_MachineBasicBlock type MachineBasicBlock *MBB; // For MO_MachineBasicBlock type
std::string *SymbolName; // For MO_ExternalSymbol type std::string *SymbolName; // For MO_ExternalSymbol type
}; } contents;
char flags; // see bit field definitions above char flags; // see bit field definitions above
MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. MachineOperandType opType:8; // Pack into 8 bits efficiently after flags.
int regNum; // register number for an explicit register int regNum; // register number for an explicit register
// will be set for a value after reg allocation // will be set for a value after reg allocation
private: private:
void zeroContents () {
memset (&contents, 0, sizeof (contents));
}
MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister) MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
: immedVal(ImmVal), : flags(0), opType(OpTy), regNum(-1) {
flags(0), zeroContents ();
opType(OpTy), }
regNum(-1) {}
MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy) MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy)
: immedVal(0), flags(UseTy), opType(OpTy), regNum(Reg) { } : flags(UseTy), opType(OpTy), regNum(Reg) {
zeroContents ();
}
MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy, MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy,
bool isPCRelative = false) bool isPCRelative = false)
: value(V), : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy), regNum(-1) {
flags(UseTy | (isPCRelative ? PCRELATIVE : 0)), zeroContents ();
opType(OpTy), contents.value = V;
regNum(-1) {
} }
MachineOperand(MachineBasicBlock *mbb) MachineOperand(MachineBasicBlock *mbb)
: MBB(mbb), flags(0), opType(MO_MachineBasicBlock), regNum(-1) { } : flags(0), opType(MO_MachineBasicBlock), regNum(-1) {
zeroContents ();
contents.MBB = mbb;
}
MachineOperand(const std::string &SymName, bool isPCRelative) MachineOperand(const std::string &SymName, bool isPCRelative)
: SymbolName(new std::string(SymName)), flags(isPCRelative ? PCRELATIVE :0), : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol), regNum(-1) {
opType(MO_ExternalSymbol), regNum(-1) {} zeroContents ();
contents.SymbolName = new std::string (SymName);
}
public: public:
MachineOperand(const MachineOperand &M) : immedVal(M.immedVal), MachineOperand(const MachineOperand &M)
flags(M.flags), : flags(M.flags), opType(M.opType), regNum(M.regNum) {
opType(M.opType), zeroContents ();
regNum(M.regNum) { contents = M.contents;
if (isExternalSymbol()) if (isExternalSymbol())
SymbolName = new std::string(M.getSymbolName()); contents.SymbolName = new std::string(M.getSymbolName());
} }
~MachineOperand() { ~MachineOperand() {
if (isExternalSymbol()) if (isExternalSymbol())
delete SymbolName; delete contents.SymbolName;
} }
const MachineOperand &operator=(const MachineOperand &MO) { const MachineOperand &operator=(const MachineOperand &MO) {
if (isExternalSymbol()) // if old operand had a symbol name, if (isExternalSymbol()) // if old operand had a symbol name,
delete SymbolName; // release old memory delete contents.SymbolName; // release old memory
immedVal = MO.immedVal; contents = MO.contents;
flags = MO.flags; flags = MO.flags;
opType = MO.opType; opType = MO.opType;
regNum = MO.regNum; regNum = MO.regNum;
if (isExternalSymbol()) if (isExternalSymbol())
SymbolName = new std::string(MO.getSymbolName()); contents.SymbolName = new std::string(MO.getSymbolName());
return *this; return *this;
} }
@ -184,9 +193,7 @@ public:
/// getUseType - Returns the MachineOperandUseType of this operand. /// getUseType - Returns the MachineOperandUseType of this operand.
/// ///
UseType getUseType() const { UseType getUseType() const { return UseType(flags & (USEFLAG|DEFFLAG)); }
return UseType(flags & (USEFLAG|DEFFLAG));
}
/// isPCRelative - This returns the value of the PCRELATIVE flag, which /// isPCRelative - This returns the value of the PCRELATIVE flag, which
/// indicates whether this operand should be emitted as a PC relative value /// indicates whether this operand should be emitted as a PC relative value
@ -205,6 +212,8 @@ public:
return opType == MO_MachineRegister || opType == MO_VirtualRegister; return opType == MO_MachineRegister || opType == MO_VirtualRegister;
} }
/// Accessors that tell you what kind of MachineOperand you're looking at.
///
bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; } bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
bool isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; } bool isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; }
bool isImmediate() const { bool isImmediate() const {
@ -215,42 +224,54 @@ public:
bool isGlobalAddress() const { return opType == MO_GlobalAddress; } bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
Value* getVRegValue() const { /// getVRegValueOrNull - Get the Value* out of a MachineOperand if it
assert(opType == MO_VirtualRegister || opType == MO_CCRegister || /// has one. This is deprecated and only used by the SPARC v9 backend.
isPCRelativeDisp()); ///
return value;
}
Value* getVRegValueOrNull() const { Value* getVRegValueOrNull() const {
return (opType == MO_VirtualRegister || opType == MO_CCRegister || return (opType == MO_VirtualRegister || opType == MO_CCRegister ||
isPCRelativeDisp()) ? value : NULL; isPCRelativeDisp()) ? contents.value : NULL;
}
/// MachineOperand accessors that only work on certain types of
/// MachineOperand...
///
Value* getVRegValue() const {
assert ((opType == MO_VirtualRegister || opType == MO_CCRegister
|| isPCRelativeDisp()) && "Wrong MachineOperand accessor");
return contents.value;
} }
int getMachineRegNum() const { int getMachineRegNum() const {
assert(opType == MO_MachineRegister); assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor");
return regNum; return regNum;
} }
int getImmedValue() const { assert(isImmediate()); return immedVal; } int getImmedValue() const {
void setImmedValue(int ImmVal) { assert(isImmediate()); immedVal = ImmVal; } assert(isImmediate() && "Wrong MachineOperand accessor");
return contents.immedVal;
}
MachineBasicBlock *getMachineBasicBlock() const { MachineBasicBlock *getMachineBasicBlock() const {
assert(isMachineBasicBlock() && "Can't get MBB in non-MBB operand!"); assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
return MBB; return contents.MBB;
}
int getFrameIndex() const {
assert(isFrameIndex() && "Wrong MachineOperand accessor");
return contents.immedVal;
} }
int getFrameIndex() const { assert(isFrameIndex()); return immedVal; }
unsigned getConstantPoolIndex() const { unsigned getConstantPoolIndex() const {
assert(isConstantPoolIndex()); assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
return immedVal; return contents.immedVal;
} }
GlobalValue *getGlobal() const { GlobalValue *getGlobal() const {
assert(isGlobalAddress()); assert(isGlobalAddress() && "Wrong MachineOperand accessor");
return (GlobalValue*)value; return (GlobalValue*)contents.value;
} }
const std::string &getSymbolName() const { const std::string &getSymbolName() const {
assert(isExternalSymbol()); assert(isExternalSymbol() && "Wrong MachineOperand accessor");
return *SymbolName; return *contents.SymbolName;
} }
/// MachineOperand methods for testing that work on any kind of
/// MachineOperand...
///
bool isUse () const { return flags & USEFLAG; } bool isUse () const { return flags & USEFLAG; }
MachineOperand& setUse () { flags |= USEFLAG; return *this; } MachineOperand& setUse () { flags |= USEFLAG; return *this; }
bool isDef () const { return flags & DEFFLAG; } bool isDef () const { return flags & DEFFLAG; }
@ -260,38 +281,52 @@ public:
bool isHiBits64 () const { return flags & HIFLAG64; } bool isHiBits64 () const { return flags & HIFLAG64; }
bool isLoBits64 () const { return flags & LOFLAG64; } bool isLoBits64 () const { return flags & LOFLAG64; }
// used to check if a machine register has been allocated to this operand /// hasAllocatedReg - Returns true iff a machine register has been
/// allocated to this operand.
///
bool hasAllocatedReg() const { bool hasAllocatedReg() const {
return (regNum >= 0 && return (regNum >= 0 &&
(opType == MO_VirtualRegister || opType == MO_CCRegister || (opType == MO_VirtualRegister || opType == MO_CCRegister ||
opType == MO_MachineRegister)); opType == MO_MachineRegister));
} }
// used to get the reg number if when one is allocated /// getReg - Returns the register number. It is a runtime error to call this
/// if a register is not allocated.
///
unsigned getReg() const { unsigned getReg() const {
assert(hasAllocatedReg()); assert(hasAllocatedReg());
return regNum; return regNum;
} }
// ********** TODO: get rid of this duplicate code! *********** /// MachineOperand mutators...
///
void setReg(unsigned Reg) { void setReg(unsigned Reg) {
// This method's comment used to say: 'TODO: get rid of this duplicate
// code.' It's not clear where the duplication is.
assert(hasAllocatedReg() && "This operand cannot have a register number!"); assert(hasAllocatedReg() && "This operand cannot have a register number!");
regNum = Reg; regNum = Reg;
} }
void setImmedValue(int immVal) {
assert(isImmediate() && "Wrong MachineOperand mutator");
contents.immedVal = immVal;
}
friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
private: private:
/// markHi32, markLo32, etc. - These methods must be accessed via
// Construction methods needed for fine-grain control. /// corresponding methods in MachineInstr. These methods are deprecated
// These must be accessed via coresponding methods in MachineInstr. /// and only used by the SPARC v9 back-end.
///
void markHi32() { flags |= HIFLAG32; } void markHi32() { flags |= HIFLAG32; }
void markLo32() { flags |= LOFLAG32; } void markLo32() { flags |= LOFLAG32; }
void markHi64() { flags |= HIFLAG64; } void markHi64() { flags |= HIFLAG64; }
void markLo64() { flags |= LOFLAG64; } void markLo64() { flags |= LOFLAG64; }
// Replaces the Value with its corresponding physical register after /// setRegForValue - Replaces the Value with its corresponding physical
// register allocation is complete /// register after register allocation is complete. This is deprecated
/// and only used by the SPARC v9 back-end.
///
void setRegForValue(int reg) { void setRegForValue(int reg) {
assert(opType == MO_VirtualRegister || opType == MO_CCRegister || assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
opType == MO_MachineRegister); opType == MO_MachineRegister);
@ -326,13 +361,13 @@ class MachineInstr {
std::vector<MachineOperand> operands; // the operands std::vector<MachineOperand> operands; // the operands
MachineInstr* prev, *next; // links for our intrusive list MachineInstr* prev, *next; // links for our intrusive list
MachineBasicBlock* parent; // pointer to the owning basic block MachineBasicBlock* parent; // pointer to the owning basic block
// OperandComplete - Return true if it's illegal to add a new operand // OperandComplete - Return true if it's illegal to add a new operand
bool OperandsComplete() const; bool OperandsComplete() const;
MachineInstr(const MachineInstr &); // DO NOT IMPLEMENT MachineInstr(const MachineInstr &); // DO NOT IMPLEMENT
void operator=(const MachineInstr&); // DO NOT IMPLEMENT void operator=(const MachineInstr&); // DO NOT IMPLEMENT
private:
// Intrusive list support // Intrusive list support
// //
friend class ilist_traits<MachineInstr>; friend class ilist_traits<MachineInstr>;
@ -358,7 +393,7 @@ public:
const MachineBasicBlock* getParent() const { return parent; } const MachineBasicBlock* getParent() const { return parent; }
MachineBasicBlock* getParent() { return parent; } MachineBasicBlock* getParent() { return parent; }
/// Accessors for opcode. /// getOpcode - Returns the opcode of this MachineInstr.
/// ///
const int getOpcode() const { return Opcode; } const int getOpcode() const { return Opcode; }

View File

@ -100,7 +100,7 @@ void MachineInstr::SetMachineOperandVal(unsigned i,
Value* V) { Value* V) {
assert(i < operands.size()); // may be explicit or implicit op assert(i < operands.size()); // may be explicit or implicit op
operands[i].opType = opTy; operands[i].opType = opTy;
operands[i].value = V; operands[i].contents.value = V;
operands[i].regNum = -1; operands[i].regNum = -1;
} }
@ -113,8 +113,8 @@ MachineInstr::SetMachineOperandConst(unsigned i,
"immed. constant cannot be defined"); "immed. constant cannot be defined");
operands[i].opType = opTy; operands[i].opType = opTy;
operands[i].value = NULL; operands[i].contents.value = NULL;
operands[i].immedVal = intValue; operands[i].contents.immedVal = intValue;
operands[i].regNum = -1; operands[i].regNum = -1;
operands[i].flags = 0; operands[i].flags = 0;
} }
@ -123,7 +123,7 @@ void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
assert(i < getNumOperands()); // must be explicit op assert(i < getNumOperands()); // must be explicit op
operands[i].opType = MachineOperand::MO_MachineRegister; operands[i].opType = MachineOperand::MO_MachineRegister;
operands[i].value = NULL; operands[i].contents.value = NULL;
operands[i].regNum = regNum; operands[i].regNum = regNum;
} }
@ -162,7 +162,7 @@ MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
notDefsAndUses && (O.isDef() && !O.isUse()) || notDefsAndUses && (O.isDef() && !O.isUse()) ||
!notDefsAndUses && O.isDef()) !notDefsAndUses && O.isDef())
{ {
O.getMachineOperand().value = newVal; O.getMachineOperand().contents.value = newVal;
++numSubst; ++numSubst;
} }
else else
@ -175,7 +175,7 @@ MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
notDefsAndUses && (getImplicitOp(i).isDef() && !getImplicitOp(i).isUse()) || notDefsAndUses && (getImplicitOp(i).isDef() && !getImplicitOp(i).isUse()) ||
!notDefsAndUses && getImplicitOp(i).isDef()) !notDefsAndUses && getImplicitOp(i).isDef())
{ {
getImplicitOp(i).value = newVal; getImplicitOp(i).contents.value = newVal;
++numSubst; ++numSubst;
} }
else else