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:
parent
3001c6e264
commit
015972103d
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue