[llvm-commits] [llvm] r148250 - in /llvm/trunk: docs/CodeGenerator.html docs/ReleaseNotes.html include/llvm/CodeGen/MachineInstrBuilder.h include/llvm/CodeGen/MachineOperand.h lib/CodeGen/MachineInstr.cpp
Jakob Stoklund Olesen
stoklund at 2pi.dk
Mon Jan 16 11:22:00 PST 2012
Author: stoklund
Date: Mon Jan 16 13:22:00 2012
New Revision: 148250
URL: http://llvm.org/viewvc/llvm-project?rev=148250&view=rev
Log:
Add a new kind of MachineOperand: MO_RegisterMask.
Register masks will be used as a compact representation of large clobber
lists. Currently, an x86 call instruction has some 40 operands
representing call-clobbered registers. That's more than 1kB of useless
operands per call site.
A register mask operand references a bit mask of call-preserved
registers, everything else is clobbered. The bit mask will typically
come from TargetRegisterInfo::getCallPreservedMask().
By abandoning ImplicitDefs for call-clobbered registers, it also becomes
possible to share call instruction descriptions between calling
conventions, and we can get rid of the WINCALL* instructions.
This patch introduces the new operand kind. Future patches will add
RegMask support to target-independent passes before finally the fixed
clobber lists can be removed from call instruction descriptions.
Modified:
llvm/trunk/docs/CodeGenerator.html
llvm/trunk/docs/ReleaseNotes.html
llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h
llvm/trunk/include/llvm/CodeGen/MachineOperand.h
llvm/trunk/lib/CodeGen/MachineInstr.cpp
Modified: llvm/trunk/docs/CodeGenerator.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=148250&r1=148249&r2=148250&view=diff
==============================================================================
--- llvm/trunk/docs/CodeGenerator.html (original)
+++ llvm/trunk/docs/CodeGenerator.html Mon Jan 16 13:22:00 2012
@@ -709,6 +709,21 @@
<!-- _______________________________________________________________________ -->
<h4>
+ <a name="callclobber">Call-clobbered registers</a>
+</h4>
+
+<div>
+
+<p>Some machine instructions, like calls, clobber a large number of physical
+ registers. Rather than adding <code><def,dead></code> operands for
+ all of them, it is possible to use an <code>MO_RegisterMask</code> operand
+ instead. The register mask operand holds a bit mask of preserved registers,
+ and everything else is considered to be clobbered by the instruction. </p>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<h4>
<a name="ssa">Machine code in SSA form</a>
</h4>
Modified: llvm/trunk/docs/ReleaseNotes.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=148250&r1=148249&r2=148250&view=diff
==============================================================================
--- llvm/trunk/docs/ReleaseNotes.html (original)
+++ llvm/trunk/docs/ReleaseNotes.html Mon Jan 16 13:22:00 2012
@@ -355,6 +355,10 @@
frozen when register allocation starts. Target hooks should use the
<code>MRI->canReserveReg(FramePtr)</code> method to avoid accidentally
disabling frame pointer elimination during register allocation.</li>
+ <li>A new kind of <code>MachineOperand</code> provides a compact
+ representation of large clobber lists on call instructions. The register
+ mask operand references a bit mask of preserved registers. Everything else is
+ clobbered.</li>
</ul>
</div>
Modified: llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h?rev=148250&r1=148249&r2=148250&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineInstrBuilder.h Mon Jan 16 13:22:00 2012
@@ -124,6 +124,11 @@
return *this;
}
+ const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
+ MI->addOperand(MachineOperand::CreateRegMask(Mask));
+ return *this;
+ }
+
const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
MI->addMemOperand(*MI->getParent()->getParent(), MMO);
return *this;
Modified: llvm/trunk/include/llvm/CodeGen/MachineOperand.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineOperand.h?rev=148250&r1=148249&r2=148250&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineOperand.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineOperand.h Mon Jan 16 13:22:00 2012
@@ -48,6 +48,7 @@
MO_ExternalSymbol, ///< Name of external global symbol
MO_GlobalAddress, ///< Address of a global value
MO_BlockAddress, ///< Address of a basic block
+ MO_RegisterMask, ///< Mask of preserved registers.
MO_Metadata, ///< Metadata reference (for debug info)
MO_MCSymbol ///< MCSymbol reference (for debug/eh info)
};
@@ -141,6 +142,7 @@
const ConstantFP *CFP; // For MO_FPImmediate.
const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
int64_t ImmVal; // For MO_Immediate.
+ const uint32_t *RegMask; // For MO_RegisterMask.
const MDNode *MD; // For MO_Metadata.
MCSymbol *Sym; // For MO_MCSymbol
@@ -220,10 +222,13 @@
bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
/// isBlockAddress - Tests if this is a MO_BlockAddress operand.
bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
+ /// isRegMask - Tests if this is a MO_RegisterMask operand.
+ bool isRegMask() const { return OpKind == MO_RegisterMask; }
/// isMetadata - Tests if this is a MO_Metadata operand.
bool isMetadata() const { return OpKind == MO_Metadata; }
bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
+
//===--------------------------------------------------------------------===//
// Accessors for Register Operands
//===--------------------------------------------------------------------===//
@@ -436,6 +441,22 @@
return Contents.OffsetedInfo.Val.SymbolName;
}
+ /// clobbersPhysReg - Returns true if this RegMask operand clobbers PhysReg.
+ bool clobbersPhysReg(unsigned PhysReg) const {
+ assert(isRegMask() && "Wrong MachineOperand accessor");
+ // See TargetRegisterInfo.h.
+ assert(PhysReg < (1u << 30) && "Not a physical register");
+ return !Contents.RegMask ||
+ !(Contents.RegMask[PhysReg / 32] & (1u << PhysReg % 32));
+ }
+
+ /// getRegMask - Returns a bit mask of registers preserved by this RegMask
+ /// operand. A NULL pointer means that all registers are clobbered.
+ const uint32_t *getRegMask() const {
+ assert(isRegMask() && "Wrong MachineOperand accessor");
+ return Contents.RegMask;
+ }
+
const MDNode *getMetadata() const {
assert(isMetadata() && "Wrong MachineOperand accessor");
return Contents.MD;
@@ -582,6 +603,23 @@
Op.setTargetFlags(TargetFlags);
return Op;
}
+ /// CreateRegMask - Creates a register mask operand referencing Mask. The
+ /// operand does not take ownership of the memory referenced by Mask, it must
+ /// remain valid for the lifetime of the operand.
+ ///
+ /// A RegMask operand represents a set of non-clobbered physical registers on
+ /// an instruction that clobbers many registers, typically a call. The bit
+ /// mask has a bit set for each physreg that is preserved by this
+ /// instruction, as described in the documentation for
+ /// TargetRegisterInfo::getCallPreservedMask().
+ ///
+ /// Any physreg with a 0 bit in the mask is clobbered by the instruction.
+ ///
+ static MachineOperand CreateRegMask(const uint32_t *Mask) {
+ MachineOperand Op(MachineOperand::MO_RegisterMask);
+ Op.Contents.RegMask = Mask;
+ return Op;
+ }
static MachineOperand CreateMetadata(const MDNode *Meta) {
MachineOperand Op(MachineOperand::MO_Metadata);
Op.Contents.MD = Meta;
Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=148250&r1=148249&r2=148250&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Mon Jan 16 13:22:00 2012
@@ -216,6 +216,8 @@
getOffset() == Other.getOffset();
case MachineOperand::MO_BlockAddress:
return getBlockAddress() == Other.getBlockAddress();
+ case MO_RegisterMask:
+ return getRegMask() == Other.getRegMask();
case MachineOperand::MO_MCSymbol:
return getMCSymbol() == Other.getMCSymbol();
case MachineOperand::MO_Metadata:
@@ -324,6 +326,9 @@
WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false);
OS << '>';
break;
+ case MachineOperand::MO_RegisterMask:
+ OS << (getRegMask() ? "<regmask>" : "<regmask:null>");
+ break;
case MachineOperand::MO_Metadata:
OS << '<';
WriteAsOperand(OS, getMetadata(), /*PrintType=*/false);
More information about the llvm-commits
mailing list