summaryrefslogtreecommitdiff
path: root/llvm/include/llvm/CodeGen/MachineBasicBlock.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/CodeGen/MachineBasicBlock.h')
-rw-r--r--llvm/include/llvm/CodeGen/MachineBasicBlock.h149
1 files changed, 125 insertions, 24 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index ccdde78a0b22e..d6cb7211cf70e 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -15,16 +15,13 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/ADT/simple_ilist.h"
+#include "llvm/ADT/SparseBitVector.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundleIterator.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/LaneBitmask.h"
-#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/BranchProbability.h"
-#include "llvm/Support/Printable.h"
#include <cassert>
#include <cstdint>
#include <functional>
@@ -39,12 +36,44 @@ class MachineFunction;
class MCSymbol;
class ModuleSlotTracker;
class Pass;
+class Printable;
class SlotIndexes;
class StringRef;
class raw_ostream;
class TargetRegisterClass;
class TargetRegisterInfo;
+// This structure uniquely identifies a basic block section.
+// Possible values are
+// {Type: Default, Number: (unsigned)} (These are regular section IDs)
+// {Type: Exception, Number: 0} (ExceptionSectionID)
+// {Type: Cold, Number: 0} (ColdSectionID)
+struct MBBSectionID {
+ enum SectionType {
+ Default = 0, // Regular section (these sections are distinguished by the
+ // Number field).
+ Exception, // Special section type for exception handling blocks
+ Cold, // Special section type for cold blocks
+ } Type;
+ unsigned Number;
+
+ MBBSectionID(unsigned N) : Type(Default), Number(N) {}
+
+ // Special unique sections for cold and exception blocks.
+ const static MBBSectionID ColdSectionID;
+ const static MBBSectionID ExceptionSectionID;
+
+ bool operator==(const MBBSectionID &Other) const {
+ return Type == Other.Type && Number == Other.Number;
+ }
+
+ bool operator!=(const MBBSectionID &Other) const { return !(*this == Other); }
+
+private:
+ // This is only used to construct the special cold and exception sections.
+ MBBSectionID(SectionType T) : Type(T), Number(0) {}
+};
+
template <> struct ilist_traits<MachineInstr> {
private:
friend class MachineBasicBlock; // Set by the owning MachineBasicBlock.
@@ -129,10 +158,25 @@ private:
/// Indicate that this basic block is the entry block of a cleanup funclet.
bool IsCleanupFuncletEntry = false;
+ /// With basic block sections, this stores the Section ID of the basic block.
+ MBBSectionID SectionID{0};
+
+ // Indicate that this basic block begins a section.
+ bool IsBeginSection = false;
+
+ // Indicate that this basic block ends a section.
+ bool IsEndSection = false;
+
+ /// Indicate that this basic block is the indirect dest of an INLINEASM_BR.
+ bool IsInlineAsmBrIndirectTarget = false;
+
/// since getSymbol is a relatively heavy-weight operation, the symbol
/// is only computed once and is cached.
mutable MCSymbol *CachedMCSymbol = nullptr;
+ /// Used during basic block sections to mark the end of a basic block.
+ MCSymbol *EndMCSymbol = nullptr;
+
// Intrusive list support
MachineBasicBlock() = default;
@@ -331,7 +375,7 @@ public:
/// Add PhysReg as live in to this block, and ensure that there is a copy of
/// PhysReg to a virtual register of class RC. Return the virtual register
/// that is a copy of the live in PhysReg.
- unsigned addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC);
+ Register addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC);
/// Remove the specified register from the live in set.
void removeLiveIn(MCPhysReg Reg,
@@ -408,6 +452,43 @@ public:
/// Indicates if this is the entry block of a cleanup funclet.
void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
+ /// Returns true if this block begins any section.
+ bool isBeginSection() const { return IsBeginSection; }
+
+ /// Returns true if this block ends any section.
+ bool isEndSection() const { return IsEndSection; }
+
+ void setIsBeginSection(bool V = true) { IsBeginSection = V; }
+
+ void setIsEndSection(bool V = true) { IsEndSection = V; }
+
+ /// Returns the section ID of this basic block.
+ MBBSectionID getSectionID() const { return SectionID; }
+
+ /// Returns the unique section ID number of this basic block.
+ unsigned getSectionIDNum() const {
+ return ((unsigned)MBBSectionID::SectionType::Cold) -
+ ((unsigned)SectionID.Type) + SectionID.Number;
+ }
+
+ /// Sets the section ID for this basic block.
+ void setSectionID(MBBSectionID V) { SectionID = V; }
+
+ /// Returns true if this block may have an INLINEASM_BR (overestimate, by
+ /// checking if any of the successors are indirect targets of any inlineasm_br
+ /// in the function).
+ bool mayHaveInlineAsmBr() const;
+
+ /// Returns true if this is the indirect dest of an INLINEASM_BR.
+ bool isInlineAsmBrIndirectTarget() const {
+ return IsInlineAsmBrIndirectTarget;
+ }
+
+ /// Indicates if this is the indirect dest of an INLINEASM_BR.
+ void setIsInlineAsmBrIndirectTarget(bool V = true) {
+ IsInlineAsmBrIndirectTarget = V;
+ }
+
/// Returns true if it is legal to hoist instructions into this block.
bool isLegalToHoistInto() const;
@@ -419,11 +500,18 @@ public:
void moveBefore(MachineBasicBlock *NewAfter);
void moveAfter(MachineBasicBlock *NewBefore);
- /// Update the terminator instructions in block to account for changes to the
- /// layout. If the block previously used a fallthrough, it may now need a
- /// branch, and if it previously used branching it may now be able to use a
- /// fallthrough.
- void updateTerminator();
+ /// Returns true if this and MBB belong to the same section.
+ bool sameSection(const MachineBasicBlock *MBB) const {
+ return getSectionID() == MBB->getSectionID();
+ }
+
+ /// Update the terminator instructions in block to account for changes to
+ /// block layout which may have been made. PreviousLayoutSuccessor should be
+ /// set to the block which may have been used as fallthrough before the block
+ /// layout was modified. If the block previously fell through to that block,
+ /// it may now need a branch. If it previously branched to another block, it
+ /// may now be able to fallthrough to the current layout successor.
+ void updateTerminator(MachineBasicBlock *PreviousLayoutSuccessor);
// Machine-CFG mutators
@@ -588,7 +676,9 @@ public:
///
/// This function updates LiveVariables, MachineDominatorTree, and
/// MachineLoopInfo, as applicable.
- MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P);
+ MachineBasicBlock *
+ SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P,
+ std::vector<SparseBitVector<>> *LiveInSets = nullptr);
/// Check if the edge between this block and the given successor \p
/// Succ, can be split. If this returns true a subsequent call to
@@ -737,16 +827,6 @@ public:
/// instead of basic block \p Old.
void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New);
- /// Various pieces of code can cause excess edges in the CFG to be inserted.
- /// If we have proven that MBB can only branch to DestA and DestB, remove any
- /// other MBB successors from the CFG. DestA and DestB can be null. Besides
- /// DestA and DestB, retain other edges leading to LandingPads (currently
- /// there can be only one; we don't check or require that here). Note it is
- /// possible that DestA and/or DestB are LandingPads.
- bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
- MachineBasicBlock *DestB,
- bool IsCond);
-
/// Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE
/// and DBG_LABEL instructions. Return UnknownLoc if there is none.
DebugLoc findDebugLoc(instr_iterator MBBI);
@@ -781,7 +861,7 @@ public:
///
/// \p Reg must be a physical register.
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
- unsigned Reg,
+ MCRegister Reg,
const_iterator Before,
unsigned Neighborhood = 10) const;
@@ -946,7 +1026,7 @@ public:
template<typename IterT>
inline IterT skipDebugInstructionsForward(IterT It, IterT End) {
while (It != End && It->isDebugInstr())
- It++;
+ ++It;
return It;
}
@@ -957,10 +1037,31 @@ inline IterT skipDebugInstructionsForward(IterT It, IterT End) {
template<class IterT>
inline IterT skipDebugInstructionsBackward(IterT It, IterT Begin) {
while (It != Begin && It->isDebugInstr())
- It--;
+ --It;
return It;
}
+/// Increment \p It, then continue incrementing it while it points to a debug
+/// instruction. A replacement for std::next.
+template <typename IterT> inline IterT next_nodbg(IterT It, IterT End) {
+ return skipDebugInstructionsForward(std::next(It), End);
+}
+
+/// Decrement \p It, then continue decrementing it while it points to a debug
+/// instruction. A replacement for std::prev.
+template <typename IterT> inline IterT prev_nodbg(IterT It, IterT Begin) {
+ return skipDebugInstructionsBackward(std::prev(It), Begin);
+}
+
+/// Construct a range iterator which begins at \p It and moves forwards until
+/// \p End is reached, skipping any debug instructions.
+template <typename IterT>
+inline auto instructionsWithoutDebug(IterT It, IterT End) {
+ return make_filter_range(make_range(It, End), [](const MachineInstr &MI) {
+ return !MI.isDebugInstr();
+ });
+}
+
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEBASICBLOCK_H