CodeGen: Push the ModuleSlotTracker through MachineOperands

Push `ModuleSlotTracker` through `MachineOperand`s, dropping the time
for `llc -print-machineinstrs` on the testcase in PR23865 from ~13
seconds to ~9 seconds.  Now `SlotTracker::processFunctionMetadata()`
accounts for only 8% of the runtime, which seems reasonable.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240845 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2015-06-26 22:06:47 +00:00
parent 982139fde2
commit a08efbfc8e
6 changed files with 63 additions and 37 deletions

View File

@ -1105,6 +1105,8 @@ public:
// Debugging support // Debugging support
// //
void print(raw_ostream &OS, bool SkipOpers = false) const; void print(raw_ostream &OS, bool SkipOpers = false) const;
void print(raw_ostream &OS, ModuleSlotTracker &MST,
bool SkipOpers = false) const;
void dump() const; void dump() const;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -27,6 +27,7 @@ namespace llvm {
class FoldingSetNodeID; class FoldingSetNodeID;
class MDNode; class MDNode;
class raw_ostream; class raw_ostream;
class ModuleSlotTracker;
/// MachinePointerInfo - This class contains a discriminated union of /// MachinePointerInfo - This class contains a discriminated union of
/// information about pointers in memory operands, relating them back to LLVM IR /// information about pointers in memory operands, relating them back to LLVM IR
@ -200,6 +201,12 @@ public:
/// ///
void Profile(FoldingSetNodeID &ID) const; void Profile(FoldingSetNodeID &ID) const;
/// Support for operator<<.
/// @{
void print(raw_ostream &OS) const;
void print(raw_ostream &OS, ModuleSlotTracker &MST) const;
/// @}
friend bool operator==(const MachineMemOperand &LHS, friend bool operator==(const MachineMemOperand &LHS,
const MachineMemOperand &RHS) { const MachineMemOperand &RHS) {
return LHS.getValue() == RHS.getValue() && return LHS.getValue() == RHS.getValue() &&
@ -219,7 +226,10 @@ public:
} }
}; };
raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO); inline raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO) {
MRO.print(OS);
return OS;
}
} // End llvm namespace } // End llvm namespace

View File

@ -27,6 +27,7 @@ class MachineBasicBlock;
class MachineInstr; class MachineInstr;
class MachineRegisterInfo; class MachineRegisterInfo;
class MDNode; class MDNode;
class ModuleSlotTracker;
class TargetMachine; class TargetMachine;
class TargetRegisterInfo; class TargetRegisterInfo;
class hash_code; class hash_code;
@ -218,6 +219,8 @@ public:
void clearParent() { ParentMI = nullptr; } void clearParent() { ParentMI = nullptr; }
void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const; void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const;
void print(raw_ostream &os, ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI = nullptr) const;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Accessors that tell you what kind of MachineOperand you're looking at. // Accessors that tell you what kind of MachineOperand you're looking at.

View File

@ -29,8 +29,7 @@ namespace llvm {
/// space), or constant pool. /// space), or constant pool.
class PseudoSourceValue { class PseudoSourceValue {
private: private:
friend raw_ostream &llvm::operator<<(raw_ostream &OS, friend class MachineMemOperand; // For printCustom().
const MachineMemOperand &MMO);
/// printCustom - Implement printing for PseudoSourceValue. This is called /// printCustom - Implement printing for PseudoSourceValue. This is called
/// from Value::print or Value's operator<<. /// from Value::print or Value's operator<<.

View File

@ -305,7 +305,7 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
OS << '\t'; OS << '\t';
if (I->isInsideBundle()) if (I->isInsideBundle())
OS << " * "; OS << " * ";
I->print(OS); I->print(OS, MST);
} }
// Print the successors of this block according to the CFG. // Print the successors of this block according to the CFG.

View File

@ -28,6 +28,7 @@
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h" #include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/Type.h" #include "llvm/IR/Type.h"
#include "llvm/IR/Value.h" #include "llvm/IR/Value.h"
#include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrDesc.h"
@ -296,10 +297,14 @@ hash_code llvm::hash_value(const MachineOperand &MO) {
llvm_unreachable("Invalid machine operand type"); llvm_unreachable("Invalid machine operand type");
} }
/// print - Print the specified machine operand.
///
void MachineOperand::print(raw_ostream &OS, void MachineOperand::print(raw_ostream &OS,
const TargetRegisterInfo *TRI) const { const TargetRegisterInfo *TRI) const {
ModuleSlotTracker DummyMST(nullptr);
print(OS, DummyMST, TRI);
}
void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI) const {
switch (getType()) { switch (getType()) {
case MachineOperand::MO_Register: case MachineOperand::MO_Register:
OS << PrintReg(getReg(), TRI, getSubReg()); OS << PrintReg(getReg(), TRI, getSubReg());
@ -387,7 +392,7 @@ void MachineOperand::print(raw_ostream &OS,
break; break;
case MachineOperand::MO_GlobalAddress: case MachineOperand::MO_GlobalAddress:
OS << "<ga:"; OS << "<ga:";
getGlobal()->printAsOperand(OS, /*PrintType=*/false); getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
if (getOffset()) OS << "+" << getOffset(); if (getOffset()) OS << "+" << getOffset();
OS << '>'; OS << '>';
break; break;
@ -398,7 +403,7 @@ void MachineOperand::print(raw_ostream &OS,
break; break;
case MachineOperand::MO_BlockAddress: case MachineOperand::MO_BlockAddress:
OS << '<'; OS << '<';
getBlockAddress()->printAsOperand(OS, /*PrintType=*/false); getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST);
if (getOffset()) OS << "+" << getOffset(); if (getOffset()) OS << "+" << getOffset();
OS << '>'; OS << '>';
break; break;
@ -505,49 +510,52 @@ uint64_t MachineMemOperand::getAlignment() const {
return MinAlign(getBaseAlignment(), getOffset()); return MinAlign(getBaseAlignment(), getOffset());
} }
raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { void MachineMemOperand::print(raw_ostream &OS) const {
assert((MMO.isLoad() || MMO.isStore()) && ModuleSlotTracker DummyMST(nullptr);
print(OS, DummyMST);
}
void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const {
assert((isLoad() || isStore()) &&
"SV has to be a load, store or both."); "SV has to be a load, store or both.");
if (MMO.isVolatile()) if (isVolatile())
OS << "Volatile "; OS << "Volatile ";
if (MMO.isLoad()) if (isLoad())
OS << "LD"; OS << "LD";
if (MMO.isStore()) if (isStore())
OS << "ST"; OS << "ST";
OS << MMO.getSize(); OS << getSize();
// Print the address information. // Print the address information.
OS << "["; OS << "[";
if (const Value *V = MMO.getValue()) if (const Value *V = getValue())
V->printAsOperand(OS, /*PrintType=*/false); V->printAsOperand(OS, /*PrintType=*/false, MST);
else if (const PseudoSourceValue *PSV = MMO.getPseudoValue()) else if (const PseudoSourceValue *PSV = getPseudoValue())
PSV->printCustom(OS); PSV->printCustom(OS);
else else
OS << "<unknown>"; OS << "<unknown>";
unsigned AS = MMO.getAddrSpace(); unsigned AS = getAddrSpace();
if (AS != 0) if (AS != 0)
OS << "(addrspace=" << AS << ')'; OS << "(addrspace=" << AS << ')';
// If the alignment of the memory reference itself differs from the alignment // If the alignment of the memory reference itself differs from the alignment
// of the base pointer, print the base alignment explicitly, next to the base // of the base pointer, print the base alignment explicitly, next to the base
// pointer. // pointer.
if (MMO.getBaseAlignment() != MMO.getAlignment()) if (getBaseAlignment() != getAlignment())
OS << "(align=" << MMO.getBaseAlignment() << ")"; OS << "(align=" << getBaseAlignment() << ")";
if (MMO.getOffset() != 0) if (getOffset() != 0)
OS << "+" << MMO.getOffset(); OS << "+" << getOffset();
OS << "]"; OS << "]";
// Print the alignment of the reference. // Print the alignment of the reference.
if (MMO.getBaseAlignment() != MMO.getAlignment() || if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize())
MMO.getBaseAlignment() != MMO.getSize()) OS << "(align=" << getAlignment() << ")";
OS << "(align=" << MMO.getAlignment() << ")";
// Print TBAA info. // Print TBAA info.
if (const MDNode *TBAAInfo = MMO.getAAInfo().TBAA) { if (const MDNode *TBAAInfo = getAAInfo().TBAA) {
OS << "(tbaa="; OS << "(tbaa=";
if (TBAAInfo->getNumOperands() > 0) if (TBAAInfo->getNumOperands() > 0)
TBAAInfo->getOperand(0)->printAsOperand(OS); TBAAInfo->getOperand(0)->printAsOperand(OS);
@ -557,7 +565,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
} }
// Print AA scope info. // Print AA scope info.
if (const MDNode *ScopeInfo = MMO.getAAInfo().Scope) { if (const MDNode *ScopeInfo = getAAInfo().Scope) {
OS << "(alias.scope="; OS << "(alias.scope=";
if (ScopeInfo->getNumOperands() > 0) if (ScopeInfo->getNumOperands() > 0)
for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) {
@ -571,7 +579,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
} }
// Print AA noalias scope info. // Print AA noalias scope info.
if (const MDNode *NoAliasInfo = MMO.getAAInfo().NoAlias) { if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) {
OS << "(noalias="; OS << "(noalias=";
if (NoAliasInfo->getNumOperands() > 0) if (NoAliasInfo->getNumOperands() > 0)
for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) {
@ -585,13 +593,11 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {
} }
// Print nontemporal info. // Print nontemporal info.
if (MMO.isNonTemporal()) if (isNonTemporal())
OS << "(nontemporal)"; OS << "(nontemporal)";
if (MMO.isInvariant()) if (isInvariant())
OS << "(invariant)"; OS << "(invariant)";
return OS;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -1526,6 +1532,12 @@ void MachineInstr::dump() const {
} }
void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const { void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
ModuleSlotTracker DummyMST(nullptr);
print(OS, DummyMST, SkipOpers);
}
void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
bool SkipOpers) const {
// We can be a bit tidier if we know the MachineFunction. // We can be a bit tidier if we know the MachineFunction.
const MachineFunction *MF = nullptr; const MachineFunction *MF = nullptr;
const TargetRegisterInfo *TRI = nullptr; const TargetRegisterInfo *TRI = nullptr;
@ -1550,7 +1562,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
!getOperand(StartOp).isImplicit(); !getOperand(StartOp).isImplicit();
++StartOp) { ++StartOp) {
if (StartOp != 0) OS << ", "; if (StartOp != 0) OS << ", ";
getOperand(StartOp).print(OS, TRI); getOperand(StartOp).print(OS, MST, TRI);
unsigned Reg = getOperand(StartOp).getReg(); unsigned Reg = getOperand(StartOp).getReg();
if (TargetRegisterInfo::isVirtualRegister(Reg)) if (TargetRegisterInfo::isVirtualRegister(Reg))
VirtRegs.push_back(Reg); VirtRegs.push_back(Reg);
@ -1577,7 +1589,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {
// Print asm string. // Print asm string.
OS << " "; OS << " ";
getOperand(InlineAsm::MIOp_AsmString).print(OS, TRI); getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI);
// Print HasSideEffects, MayLoad, MayStore, IsAlignStack // Print HasSideEffects, MayLoad, MayStore, IsAlignStack
unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
@ -1645,7 +1657,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
if (DIV && !DIV->getName().empty()) if (DIV && !DIV->getName().empty())
OS << "!\"" << DIV->getName() << '\"'; OS << "!\"" << DIV->getName() << '\"';
else else
MO.print(OS, TRI); MO.print(OS, MST, TRI);
} else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { } else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) {
OS << TRI->getSubRegIndexName(MO.getImm()); OS << TRI->getSubRegIndexName(MO.getImm());
} else if (i == AsmDescOp && MO.isImm()) { } else if (i == AsmDescOp && MO.isImm()) {
@ -1679,7 +1691,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
// Compute the index of the next operand descriptor. // Compute the index of the next operand descriptor.
AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag);
} else } else
MO.print(OS, TRI); MO.print(OS, MST, TRI);
} }
// Briefly indicate whether any call clobbers were omitted. // Briefly indicate whether any call clobbers were omitted.
@ -1704,7 +1716,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const {
OS << " mem:"; OS << " mem:";
for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); for (mmo_iterator i = memoperands_begin(), e = memoperands_end();
i != e; ++i) { i != e; ++i) {
OS << **i; (*i)->print(OS, MST);
if (std::next(i) != e) if (std::next(i) != e)
OS << " "; OS << " ";
} }