diff options
-rw-r--r-- | llvm/lib/CodeGen/MachineOutliner.cpp | 65 |
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() { |