Shrink MachineOperand from 40 to 32 bytes on 64-bit hosts.

Pull an unsigned out of the Contents union such that it has the same size as two
pointers and no padding.

Arrange members such that the Contents union and all pointers can be 8-byte
aligned without padding.

This speeds up code generation by 0.8% on a 64-bit host. 32-bit hosts should be
unaffected.

llvm-svn: 116857
This commit is contained in:
Jakob Stoklund Olesen 2010-10-19 20:56:32 +00:00
parent c57f64d1bf
commit a4941690cc
2 changed files with 21 additions and 9 deletions

View File

@ -94,6 +94,15 @@ private:
/// not a real instruction. Such uses should be ignored during codegen.
bool IsDebug : 1;
/// SmallContents - Thisreally should be part of the Contents union, but lives
/// out here so we can get a better packed struct.
/// MO_Register: Register number.
/// OffsetedInfo: Low bits of offset.
union {
unsigned RegNo; // For MO_Register.
unsigned OffsetLo; // Matches Contents.OffsetedInfo.OffsetHi.
} SmallContents;
/// ParentMI - This is the instruction that this operand is embedded into.
/// This is valid for all operand types, when the operand is in an instr.
MachineInstr *ParentMI;
@ -107,7 +116,7 @@ private:
MCSymbol *Sym; // For MO_MCSymbol
struct { // For MO_Register.
unsigned RegNo;
// Register number is in SmallContents.RegNo.
MachineOperand **Prev; // Access list for register.
MachineOperand *Next;
} Reg;
@ -121,7 +130,8 @@ private:
const GlobalValue *GV; // For MO_GlobalAddress.
const BlockAddress *BA; // For MO_BlockAddress.
} Val;
int64_t Offset; // An offset from the object.
// Low bits of offset are in SmallContents.OffsetLo.
int OffsetHi; // An offset from the object, high 32 bits.
} OffsetedInfo;
} Contents;
@ -180,7 +190,7 @@ public:
/// getReg - Returns the register number.
unsigned getReg() const {
assert(isReg() && "This is not a register operand!");
return Contents.Reg.RegNo;
return SmallContents.RegNo;
}
unsigned getSubReg() const {
@ -349,7 +359,8 @@ public:
int64_t getOffset() const {
assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
"Wrong MachineOperand accessor");
return Contents.OffsetedInfo.Offset;
return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
SmallContents.OffsetLo;
}
const char *getSymbolName() const {
@ -374,7 +385,8 @@ public:
void setOffset(int64_t Offset) {
assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
"Wrong MachineOperand accessor");
Contents.OffsetedInfo.Offset = Offset;
SmallContents.OffsetLo = unsigned(Offset);
Contents.OffsetedInfo.OffsetHi = int(Offset >> 32);
}
void setIndex(int Idx) {
@ -438,7 +450,7 @@ public:
Op.IsUndef = isUndef;
Op.IsEarlyClobber = isEarlyClobber;
Op.IsDebug = isDebug;
Op.Contents.Reg.RegNo = Reg;
Op.SmallContents.RegNo = Reg;
Op.Contents.Reg.Prev = 0;
Op.Contents.Reg.Next = 0;
Op.SubReg = SubReg;

View File

@ -102,13 +102,13 @@ void MachineOperand::setReg(unsigned Reg) {
if (MachineBasicBlock *MBB = MI->getParent())
if (MachineFunction *MF = MBB->getParent()) {
RemoveRegOperandFromRegInfo();
Contents.Reg.RegNo = Reg;
SmallContents.RegNo = Reg;
AddRegOperandToRegInfo(&MF->getRegInfo());
return;
}
// Otherwise, just change the register, no problem. :)
Contents.Reg.RegNo = Reg;
SmallContents.RegNo = Reg;
}
void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx,
@ -159,7 +159,7 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
} else {
// Otherwise, change this to a register and set the reg#.
OpKind = MO_Register;
Contents.Reg.RegNo = Reg;
SmallContents.RegNo = Reg;
// If this operand is embedded in a function, add the operand to the
// register's use/def list.