summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/MachineOutliner.cpp65
1 files changed, 47 insertions, 18 deletions
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 56b3fe202f0..5032b70e872 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -640,18 +640,24 @@ struct InstructionMapper {
/// Maps \p *It to a legal integer.
///
- /// Updates \p InstrList, \p UnsignedVec, \p InstructionIntegerMap,
- /// \p IntegerInstructionMap, and \p LegalInstrNumber.
+ /// Updates \p InstrListForMBB, \p UnsignedVecForMBB, \p
+ /// InstructionIntegerMap, \p IntegerInstructionMap, and \p LegalInstrNumber.
///
/// \returns The integer that \p *It was mapped to.
- unsigned mapToLegalUnsigned(MachineBasicBlock::iterator &It) {
+ unsigned mapToLegalUnsigned(
+ MachineBasicBlock::iterator &It, unsigned &NumLegalInBlock,
+ std::vector<unsigned> &UnsignedVecForMBB,
+ std::vector<MachineBasicBlock::iterator> &InstrListForMBB) {
// We added something legal, so we should unset the AddedLegalLastTime
// flag.
AddedIllegalLastTime = false;
+ // Keep track of the number of legal instructions we insert.
+ NumLegalInBlock++;
+
// Get the integer for this instruction or give it the current
// LegalInstrNumber.
- InstrList.push_back(It);
+ InstrListForMBB.push_back(It);
MachineInstr &MI = *It;
bool WasInserted;
DenseMap<MachineInstr *, unsigned, MachineInstrExpressionTrait>::iterator
@@ -666,7 +672,7 @@ struct InstructionMapper {
IntegerInstructionMap.insert(std::make_pair(MINumber, &MI));
}
- UnsignedVec.push_back(MINumber);
+ UnsignedVecForMBB.push_back(MINumber);
// Make sure we don't overflow or use any integers reserved by the DenseMap.
if (LegalInstrNumber >= IllegalInstrNumber)
@@ -682,10 +688,13 @@ struct InstructionMapper {
/// Maps \p *It to an illegal integer.
///
- /// Updates \p InstrList, \p UnsignedVec, and \p IllegalInstrNumber.
+ /// Updates \p InstrListForMBB, \p UnsignedVecForMBB, and \p
+ /// IllegalInstrNumber.
///
/// \returns The integer that \p *It was mapped to.
- unsigned mapToIllegalUnsigned(MachineBasicBlock::iterator &It) {
+ unsigned mapToIllegalUnsigned(
+ MachineBasicBlock::iterator &It, std::vector<unsigned> &UnsignedVecForMBB,
+ std::vector<MachineBasicBlock::iterator> &InstrListForMBB) {
// Only add one illegal number per range of legal numbers.
if (AddedIllegalLastTime)
return IllegalInstrNumber;
@@ -694,8 +703,8 @@ struct InstructionMapper {
AddedIllegalLastTime = true;
unsigned MINumber = IllegalInstrNumber;
- InstrList.push_back(It);
- UnsignedVec.push_back(IllegalInstrNumber);
+ InstrListForMBB.push_back(It);
+ UnsignedVecForMBB.push_back(IllegalInstrNumber);
IllegalInstrNumber--;
assert(LegalInstrNumber < IllegalInstrNumber &&
@@ -724,22 +733,34 @@ struct InstructionMapper {
const TargetInstrInfo &TII) {
unsigned Flags = TII.getMachineOutlinerMBBFlags(MBB);
MachineBasicBlock::iterator It = MBB.begin();
+
+ // The number of instructions in this block that will be considered for
+ // outlining.
+ unsigned NumLegalInBlock = 0;
+
+ // FIXME: Should this all just be handled in the target, rather than using
+ // repeated calls to getOutliningType?
+ std::vector<unsigned> UnsignedVecForMBB;
+ std::vector<MachineBasicBlock::iterator> InstrListForMBB;
+
for (MachineBasicBlock::iterator Et = MBB.end(); It != Et; It++) {
// Keep track of where this instruction is in the module.
switch (TII.getOutliningType(It, Flags)) {
case InstrType::Illegal:
- mapToIllegalUnsigned(It);
+ mapToIllegalUnsigned(It, UnsignedVecForMBB, InstrListForMBB);
break;
case InstrType::Legal:
- mapToLegalUnsigned(It);
+ mapToLegalUnsigned(It, NumLegalInBlock, UnsignedVecForMBB,
+ InstrListForMBB);
break;
case InstrType::LegalTerminator:
- mapToLegalUnsigned(It);
+ mapToLegalUnsigned(It, NumLegalInBlock, UnsignedVecForMBB,
+ InstrListForMBB);
// The instruction also acts as a terminator, so we have to record that
// in the string.
- mapToIllegalUnsigned(It);
+ mapToIllegalUnsigned(It, UnsignedVecForMBB, InstrListForMBB);
break;
case InstrType::Invisible:
@@ -750,11 +771,19 @@ struct InstructionMapper {
}
}
- // After we're done every insertion, uniquely terminate this part of the
- // "string". This makes sure we won't match across basic block or function
- // boundaries since the "end" is encoded uniquely and thus appears in no
- // repeated substring.
- mapToIllegalUnsigned(It);
+ // Are there enough legal instructions in the block for outlining to be
+ // possible?
+ if (NumLegalInBlock > 1) {
+ // After we're done every insertion, uniquely terminate this part of the
+ // "string". This makes sure we won't match across basic block or function
+ // boundaries since the "end" is encoded uniquely and thus appears in no
+ // repeated substring.
+ mapToIllegalUnsigned(It, UnsignedVecForMBB, InstrListForMBB);
+ InstrList.insert(InstrList.end(), InstrListForMBB.begin(),
+ InstrListForMBB.end());
+ UnsignedVec.insert(UnsignedVec.end(), UnsignedVecForMBB.begin(),
+ UnsignedVecForMBB.end());
+ }
}
InstructionMapper() {
OpenPOWER on IntegriCloud