aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineOutliner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/MachineOutliner.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineOutliner.cpp50
1 files changed, 36 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 5032b70..c69bfec 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -640,18 +640,26 @@ struct InstructionMapper {
/// Maps \p *It to a legal integer.
///
- /// Updates \p InstrListForMBB, \p UnsignedVecForMBB, \p
- /// InstructionIntegerMap, \p IntegerInstructionMap, and \p LegalInstrNumber.
+ /// Updates \p CanOutlineWithPrevInstr, \p HaveLegalRange, \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 &NumLegalInBlock,
+ MachineBasicBlock::iterator &It, bool &CanOutlineWithPrevInstr,
+ bool &HaveLegalRange, unsigned &NumLegalInBlock,
std::vector<unsigned> &UnsignedVecForMBB,
std::vector<MachineBasicBlock::iterator> &InstrListForMBB) {
// We added something legal, so we should unset the AddedLegalLastTime
// flag.
AddedIllegalLastTime = false;
+ // If we have at least two adjacent legal instructions (which may have
+ // invisible instructions in between), remember that.
+ if (CanOutlineWithPrevInstr)
+ HaveLegalRange = true;
+ CanOutlineWithPrevInstr = true;
+
// Keep track of the number of legal instructions we insert.
NumLegalInBlock++;
@@ -692,9 +700,12 @@ struct InstructionMapper {
/// IllegalInstrNumber.
///
/// \returns The integer that \p *It was mapped to.
- unsigned mapToIllegalUnsigned(
- MachineBasicBlock::iterator &It, std::vector<unsigned> &UnsignedVecForMBB,
- std::vector<MachineBasicBlock::iterator> &InstrListForMBB) {
+ unsigned mapToIllegalUnsigned(MachineBasicBlock::iterator &It,
+ bool &CanOutlineWithPrevInstr, std::vector<unsigned> &UnsignedVecForMBB,
+ std::vector<MachineBasicBlock::iterator> &InstrListForMBB) {
+ // Can't outline an illegal instruction. Set the flag.
+ CanOutlineWithPrevInstr = false;
+
// Only add one illegal number per range of legal numbers.
if (AddedIllegalLastTime)
return IllegalInstrNumber;
@@ -738,6 +749,14 @@ struct InstructionMapper {
// outlining.
unsigned NumLegalInBlock = 0;
+ // True if we have at least two legal instructions which aren't separated
+ // by an illegal instruction.
+ bool HaveLegalRange = false;
+
+ // True if we can perform outlining given the last mapped (non-invisible)
+ // instruction. This lets us know if we have a legal range.
+ bool CanOutlineWithPrevInstr = false;
+
// FIXME: Should this all just be handled in the target, rather than using
// repeated calls to getOutliningType?
std::vector<unsigned> UnsignedVecForMBB;
@@ -747,20 +766,22 @@ struct InstructionMapper {
// Keep track of where this instruction is in the module.
switch (TII.getOutliningType(It, Flags)) {
case InstrType::Illegal:
- mapToIllegalUnsigned(It, UnsignedVecForMBB, InstrListForMBB);
+ mapToIllegalUnsigned(It, CanOutlineWithPrevInstr,
+ UnsignedVecForMBB, InstrListForMBB);
break;
case InstrType::Legal:
- mapToLegalUnsigned(It, NumLegalInBlock, UnsignedVecForMBB,
- InstrListForMBB);
+ mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
+ NumLegalInBlock, UnsignedVecForMBB, InstrListForMBB);
break;
case InstrType::LegalTerminator:
- mapToLegalUnsigned(It, NumLegalInBlock, UnsignedVecForMBB,
- InstrListForMBB);
+ mapToLegalUnsigned(It, CanOutlineWithPrevInstr, HaveLegalRange,
+ NumLegalInBlock, UnsignedVecForMBB, InstrListForMBB);
// The instruction also acts as a terminator, so we have to record that
// in the string.
- mapToIllegalUnsigned(It, UnsignedVecForMBB, InstrListForMBB);
+ mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
+ InstrListForMBB);
break;
case InstrType::Invisible:
@@ -773,12 +794,13 @@ struct InstructionMapper {
// Are there enough legal instructions in the block for outlining to be
// possible?
- if (NumLegalInBlock > 1) {
+ if (HaveLegalRange) {
// 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);
+ mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB,
+ InstrListForMBB);
InstrList.insert(InstrList.end(), InstrListForMBB.begin(),
InstrListForMBB.end());
UnsignedVec.insert(UnsignedVec.end(), UnsignedVecForMBB.begin(),