2017-05-25 01:10:29 +02:00
|
|
|
//===- llvm/CodeGen/MachineBasicBlock.h -------------------------*- C++ -*-===//
|
2005-04-21 22:39:54 +02:00
|
|
|
//
|
2003-10-20 22:19:47 +02:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:59:42 +01:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-21 22:39:54 +02:00
|
|
|
//
|
2003-10-20 22:19:47 +02:00
|
|
|
//===----------------------------------------------------------------------===//
|
2005-04-21 22:39:54 +02:00
|
|
|
//
|
2002-10-27 21:49:47 +01:00
|
|
|
// Collect the sequence of machine instructions for a basic block.
|
|
|
|
//
|
2002-10-28 02:21:55 +01:00
|
|
|
//===----------------------------------------------------------------------===//
|
2002-07-09 00:40:34 +02:00
|
|
|
|
2002-10-28 01:28:31 +01:00
|
|
|
#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H
|
|
|
|
#define LLVM_CODEGEN_MACHINEBASICBLOCK_H
|
2002-07-09 00:40:34 +02:00
|
|
|
|
2004-09-02 00:55:40 +02:00
|
|
|
#include "llvm/ADT/GraphTraits.h"
|
2017-05-25 01:10:29 +02:00
|
|
|
#include "llvm/ADT/ilist.h"
|
|
|
|
#include "llvm/ADT/ilist_node.h"
|
2016-02-27 07:40:41 +01:00
|
|
|
#include "llvm/ADT/iterator_range.h"
|
2017-05-25 01:10:29 +02:00
|
|
|
#include "llvm/ADT/simple_ilist.h"
|
2012-12-03 18:02:12 +01:00
|
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
2017-06-06 13:49:48 +02:00
|
|
|
#include "llvm/CodeGen/MachineInstrBundleIterator.h"
|
2017-05-25 01:10:29 +02:00
|
|
|
#include "llvm/IR/DebugLoc.h"
|
2016-12-15 15:36:06 +01:00
|
|
|
#include "llvm/MC/LaneBitmask.h"
|
2015-08-26 00:05:55 +02:00
|
|
|
#include "llvm/MC/MCRegisterInfo.h"
|
2017-06-06 13:49:48 +02:00
|
|
|
#include "llvm/Support/BranchProbability.h"
|
2017-12-04 18:18:51 +01:00
|
|
|
#include "llvm/Support/Printable.h"
|
2017-05-25 01:10:29 +02:00
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
2011-03-04 01:15:36 +01:00
|
|
|
#include <functional>
|
2017-05-25 01:10:29 +02:00
|
|
|
#include <iterator>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2003-11-11 23:41:34 +01:00
|
|
|
|
|
|
|
namespace llvm {
|
2008-07-28 23:51:04 +02:00
|
|
|
|
|
|
|
class BasicBlock;
|
|
|
|
class MachineFunction;
|
2010-02-10 02:04:16 +01:00
|
|
|
class MCSymbol;
|
2017-05-25 01:10:29 +02:00
|
|
|
class ModuleSlotTracker;
|
|
|
|
class Pass;
|
2010-10-26 22:21:46 +02:00
|
|
|
class SlotIndexes;
|
2010-02-10 02:04:16 +01:00
|
|
|
class StringRef;
|
2009-07-24 12:36:58 +02:00
|
|
|
class raw_ostream;
|
2017-05-25 01:10:29 +02:00
|
|
|
class TargetRegisterClass;
|
|
|
|
class TargetRegisterInfo;
|
2003-11-11 23:41:34 +01:00
|
|
|
|
2016-08-30 20:40:47 +02:00
|
|
|
template <> struct ilist_traits<MachineInstr> {
|
2008-09-20 20:02:18 +02:00
|
|
|
private:
|
2016-08-30 20:40:47 +02:00
|
|
|
friend class MachineBasicBlock; // Set by the owning MachineBasicBlock.
|
2017-05-25 01:10:29 +02:00
|
|
|
|
2016-08-30 20:40:47 +02:00
|
|
|
MachineBasicBlock *Parent;
|
2004-02-12 20:12:03 +01:00
|
|
|
|
2017-05-25 01:10:29 +02:00
|
|
|
using instr_iterator =
|
|
|
|
simple_ilist<MachineInstr, ilist_sentinel_tracking<true>>::iterator;
|
2016-09-11 18:38:18 +02:00
|
|
|
|
2008-07-08 01:14:23 +02:00
|
|
|
public:
|
2016-08-30 20:40:47 +02:00
|
|
|
void addNodeToList(MachineInstr *N);
|
|
|
|
void removeNodeFromList(MachineInstr *N);
|
2018-07-16 20:51:40 +02:00
|
|
|
void transferNodesFromList(ilist_traits &FromList, instr_iterator First,
|
2016-09-11 18:38:18 +02:00
|
|
|
instr_iterator Last);
|
2016-08-30 20:40:47 +02:00
|
|
|
void deleteNode(MachineInstr *MI);
|
2004-02-12 20:12:03 +01:00
|
|
|
};
|
|
|
|
|
ADT: Avoid relying on UB in ilist_node::getNextNode()
Re-implement `ilist_node::getNextNode()` and `getPrevNode()` without
relying on the sentinel having a "next" pointer. Instead, get access to
the owning list and compare against the `begin()` and `end()` iterators.
This only works when the node *can* get access to the owning list. The
new support is in `ilist_node_with_parent<>`, and any class `Ty`
inheriting from `ilist_node<NodeTy>` that wants `getNextNode()` and/or
`getPrevNode()` should inherit from
`ilist_node_with_parent<NodeTy, ParentTy>` instead. The requirements:
- `NodeTy` must have a `getParent()` function that returns the parent.
- `ParentTy` must have a `getSublistAccess()` static that, given a(n
ignored) `NodeTy*` (to determine which list), returns a member field
pointer to the appropriate `ilist<>`.
This isn't the cleanest way to get access to the owning list, but it
leverages the API already used in the IR hierarchy (see, e.g.,
`Instruction::getSublistAccess()`).
If anyone feels like ripping out the calls to `getNextNode()` and
`getPrevNode()` and replacing with direct iterator logic, they can also
remove the access function, etc., but as an incremental step, I'm
maintaining the API where it's currently used in tree.
If these requirements are *not* met, call sites with access to the ilist
can call `iplist<NodeTy>::getNextNode(NodeTy*)` directly, as in
ilistTest.cpp.
Why rewrite this?
The old code was broken, calling `getNext()` on a sentinel that possibly
didn't have a "next" pointer at all! The new code avoids that
particular flavour of UB (see the commit message for r252538 for more
details about the "lucky" memory layout that made this function so
interesting).
There's still some UB here: the end iterator gets downcast to `NodeTy*`,
even when it's a sentinel (which is typically
`ilist_half_node<NodeTy*>`). I'll tackle that in follow-up commits.
See this llvm-dev thread for more details:
http://lists.llvm.org/pipermail/llvm-dev/2015-October/091115.html
What's the danger?
There might be some code that relies on `getNextNode()` or
`getPrevNode()` *never* returning `nullptr` -- i.e., that relies on them
being broken when the sentinel is an `ilist_half_node<NodeTy>`. I tried
to root out those cases with the audits I did leading up to r252380, but
it's possible I missed one or two. I hope not.
(If (1) you have out-of-tree code, (2) you've reverted r252380
temporarily, and (3) you get some weird crashes with this commit, then I
recommend un-reverting r252380 and auditing the compile errors looking
for "strange" implicit conversions.)
llvm-svn: 252694
2015-11-11 03:26:42 +01:00
|
|
|
class MachineBasicBlock
|
|
|
|
: public ilist_node_with_parent<MachineBasicBlock, MachineFunction> {
|
2015-09-09 20:08:03 +02:00
|
|
|
public:
|
|
|
|
/// Pair of physical register and lane mask.
|
|
|
|
/// This is not simply a std::pair typedef because the members should be named
|
|
|
|
/// clearly as they both have an integer type.
|
|
|
|
struct RegisterMaskPair {
|
|
|
|
public:
|
|
|
|
MCPhysReg PhysReg;
|
2015-09-25 23:51:14 +02:00
|
|
|
LaneBitmask LaneMask;
|
2015-09-09 20:08:03 +02:00
|
|
|
|
2015-09-25 23:51:14 +02:00
|
|
|
RegisterMaskPair(MCPhysReg PhysReg, LaneBitmask LaneMask)
|
2015-09-09 20:08:03 +02:00
|
|
|
: PhysReg(PhysReg), LaneMask(LaneMask) {}
|
|
|
|
};
|
|
|
|
|
2015-10-06 23:48:31 +02:00
|
|
|
private:
|
2017-05-25 01:10:29 +02:00
|
|
|
using Instructions = ilist<MachineInstr, ilist_sentinel_tracking<true>>;
|
|
|
|
|
2004-02-12 03:27:10 +01:00
|
|
|
Instructions Insts;
|
2003-07-27 01:30:37 +02:00
|
|
|
const BasicBlock *BB;
|
2004-05-12 23:35:20 +02:00
|
|
|
int Number;
|
2007-12-31 05:56:33 +01:00
|
|
|
MachineFunction *xParent;
|
2011-06-16 22:22:37 +02:00
|
|
|
|
2015-08-06 14:49:40 +02:00
|
|
|
/// Keep track of the predecessor / successor basic blocks.
|
2007-02-10 03:38:19 +01:00
|
|
|
std::vector<MachineBasicBlock *> Predecessors;
|
|
|
|
std::vector<MachineBasicBlock *> Successors;
|
|
|
|
|
2015-11-04 22:37:58 +01:00
|
|
|
/// Keep track of the probabilities to the successors. This vector has the
|
|
|
|
/// same order as Successors, or it is empty if we don't use it (disable
|
|
|
|
/// optimization).
|
|
|
|
std::vector<BranchProbability> Probs;
|
2017-05-25 01:10:29 +02:00
|
|
|
using probability_iterator = std::vector<BranchProbability>::iterator;
|
|
|
|
using const_probability_iterator =
|
|
|
|
std::vector<BranchProbability>::const_iterator;
|
2015-11-04 22:37:58 +01:00
|
|
|
|
2017-11-02 23:26:51 +01:00
|
|
|
Optional<uint64_t> IrrLoopHeaderWeight;
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Keep track of the physical registers that are livein of the basicblock.
|
2017-05-25 01:10:29 +02:00
|
|
|
using LiveInVector = std::vector<RegisterMaskPair>;
|
2015-08-26 00:05:55 +02:00
|
|
|
LiveInVector LiveIns;
|
2008-02-28 01:43:03 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Alignment of the basic block. Zero if the basic block does not need to be
|
|
|
|
/// aligned. The alignment is specified as log2(bytes).
|
2015-08-28 01:27:47 +02:00
|
|
|
unsigned Alignment = 0;
|
2011-12-06 02:26:19 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Indicate that this basic block is entered via an exception handler.
|
2015-08-28 01:27:47 +02:00
|
|
|
bool IsEHPad = false;
|
2007-02-10 03:38:19 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Indicate that this basic block is potentially the target of an indirect
|
|
|
|
/// branch.
|
2015-08-28 01:27:47 +02:00
|
|
|
bool AddressTaken = false;
|
|
|
|
|
[WebAssembly] Add functions for EHScopes
Summary:
There are functions using the term 'funclet' to refer to both
1. an EH scopes, the structure of BBs that starts with
catchpad/cleanuppad and ends with catchret/cleanupret, and
2. a small function that gets outlined in AsmPrinter, which is the
original meaning of 'funclet'.
So far the two have been the same thing; EH scopes are always outlined
in AsmPrinter as funclets at the end of the compilation pipeline. But
now wasm also uses scope-based EH but does not outline those, so we now
need to correctly distinguish those two use cases in functions.
This patch splits `MachineBasicBlock::isFuncletEntry` into
`isFuncletEntry` and `isEHScopeEntry`, and
`MachineFunction::hasFunclets` into `hasFunclets` and `hasEHScopes`, in
order to distinguish the two different use cases. And this also changes
some uses of the term 'funclet' to 'scope' in `getFuncletMembership` and
change the function name to `getEHScopeMembership` because this function
is not about outlined funclets but about EH scope memberships.
This change is in the same vein as D45559.
Reviewers: majnemer, dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D47005
llvm-svn: 333045
2018-05-23 02:32:46 +02:00
|
|
|
/// Indicate that this basic block is the entry block of an EH scope, i.e.,
|
|
|
|
/// the block that used to have a catchpad or cleanuppad instruction in the
|
|
|
|
/// LLVM IR.
|
|
|
|
bool IsEHScopeEntry = false;
|
|
|
|
|
2015-08-28 01:27:47 +02:00
|
|
|
/// Indicate that this basic block is the entry block of an EH funclet.
|
|
|
|
bool IsEHFuncletEntry = false;
|
2009-10-30 02:27:03 +01:00
|
|
|
|
2015-09-29 22:12:33 +02:00
|
|
|
/// Indicate that this basic block is the entry block of a cleanup funclet.
|
|
|
|
bool IsCleanupFuncletEntry = false;
|
|
|
|
|
2018-05-01 17:54:18 +02:00
|
|
|
/// since getSymbol is a relatively heavy-weight operation, the symbol
|
2013-04-22 23:21:08 +02:00
|
|
|
/// is only computed once and is cached.
|
2015-08-28 01:27:47 +02:00
|
|
|
mutable MCSymbol *CachedMCSymbol = nullptr;
|
2013-04-22 23:21:08 +02:00
|
|
|
|
2008-07-28 23:51:04 +02:00
|
|
|
// Intrusive list support
|
2017-05-25 01:10:29 +02:00
|
|
|
MachineBasicBlock() = default;
|
2008-07-28 23:51:04 +02:00
|
|
|
|
2015-09-29 21:46:09 +02:00
|
|
|
explicit MachineBasicBlock(MachineFunction &MF, const BasicBlock *BB);
|
2008-07-08 01:14:23 +02:00
|
|
|
|
2008-07-18 01:49:46 +02:00
|
|
|
~MachineBasicBlock();
|
2004-05-24 09:14:35 +02:00
|
|
|
|
2008-07-08 01:14:23 +02:00
|
|
|
// MachineBasicBlocks are allocated and owned by MachineFunction.
|
|
|
|
friend class MachineFunction;
|
2005-04-21 22:39:54 +02:00
|
|
|
|
2008-07-08 01:14:23 +02:00
|
|
|
public:
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return the LLVM basic block that this instance corresponded to originally.
|
|
|
|
/// Note that this may be NULL if this instance does not correspond directly
|
|
|
|
/// to an LLVM basic block.
|
2003-07-27 01:30:37 +02:00
|
|
|
const BasicBlock *getBasicBlock() const { return BB; }
|
2004-02-19 17:13:54 +01:00
|
|
|
|
2017-02-18 01:41:16 +01:00
|
|
|
/// Return the name of the corresponding LLVM basic block, or an empty string.
|
2009-11-20 02:17:03 +01:00
|
|
|
StringRef getName() const;
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return a formatted string to identify this block and its parent function.
|
2012-03-07 01:18:18 +01:00
|
|
|
std::string getFullName() const;
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Test whether this block is potentially the target of an indirect branch.
|
2009-10-30 02:27:03 +01:00
|
|
|
bool hasAddressTaken() const { return AddressTaken; }
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Set this block to reflect that it potentially is the target of an indirect
|
|
|
|
/// branch.
|
2009-10-30 02:27:03 +01:00
|
|
|
void setHasAddressTaken() { AddressTaken = true; }
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return the MachineFunction containing this basic block.
|
2007-12-31 05:56:33 +01:00
|
|
|
const MachineFunction *getParent() const { return xParent; }
|
|
|
|
MachineFunction *getParent() { return xParent; }
|
2004-02-19 17:13:54 +01:00
|
|
|
|
2017-05-25 01:10:29 +02:00
|
|
|
using instr_iterator = Instructions::iterator;
|
|
|
|
using const_instr_iterator = Instructions::const_iterator;
|
|
|
|
using reverse_instr_iterator = Instructions::reverse_iterator;
|
|
|
|
using const_reverse_instr_iterator = Instructions::const_reverse_iterator;
|
2011-12-06 23:12:01 +01:00
|
|
|
|
2017-05-25 01:10:29 +02:00
|
|
|
using iterator = MachineInstrBundleIterator<MachineInstr>;
|
|
|
|
using const_iterator = MachineInstrBundleIterator<const MachineInstr>;
|
|
|
|
using reverse_iterator = MachineInstrBundleIterator<MachineInstr, true>;
|
|
|
|
using const_reverse_iterator =
|
|
|
|
MachineInstrBundleIterator<const MachineInstr, true>;
|
2002-07-09 00:40:34 +02:00
|
|
|
|
2008-05-05 20:30:58 +02:00
|
|
|
unsigned size() const { return (unsigned)Insts.size(); }
|
2002-07-09 00:40:34 +02:00
|
|
|
bool empty() const { return Insts.empty(); }
|
|
|
|
|
2014-05-24 15:13:17 +02:00
|
|
|
MachineInstr &instr_front() { return Insts.front(); }
|
|
|
|
MachineInstr &instr_back() { return Insts.back(); }
|
|
|
|
const MachineInstr &instr_front() const { return Insts.front(); }
|
|
|
|
const MachineInstr &instr_back() const { return Insts.back(); }
|
|
|
|
|
|
|
|
MachineInstr &front() { return Insts.front(); }
|
|
|
|
MachineInstr &back() { return *--end(); }
|
|
|
|
const MachineInstr &front() const { return Insts.front(); }
|
|
|
|
const MachineInstr &back() const { return *--end(); }
|
2002-07-09 00:40:34 +02:00
|
|
|
|
2011-12-14 03:11:42 +01:00
|
|
|
instr_iterator instr_begin() { return Insts.begin(); }
|
|
|
|
const_instr_iterator instr_begin() const { return Insts.begin(); }
|
|
|
|
instr_iterator instr_end() { return Insts.end(); }
|
|
|
|
const_instr_iterator instr_end() const { return Insts.end(); }
|
|
|
|
reverse_instr_iterator instr_rbegin() { return Insts.rbegin(); }
|
|
|
|
const_reverse_instr_iterator instr_rbegin() const { return Insts.rbegin(); }
|
|
|
|
reverse_instr_iterator instr_rend () { return Insts.rend(); }
|
|
|
|
const_reverse_instr_iterator instr_rend () const { return Insts.rend(); }
|
2011-12-06 23:12:01 +01:00
|
|
|
|
2017-05-25 01:10:29 +02:00
|
|
|
using instr_range = iterator_range<instr_iterator>;
|
|
|
|
using const_instr_range = iterator_range<const_instr_iterator>;
|
2016-02-27 07:40:41 +01:00
|
|
|
instr_range instrs() { return instr_range(instr_begin(), instr_end()); }
|
|
|
|
const_instr_range instrs() const {
|
|
|
|
return const_instr_range(instr_begin(), instr_end());
|
|
|
|
}
|
|
|
|
|
2012-06-11 17:11:12 +02:00
|
|
|
iterator begin() { return instr_begin(); }
|
|
|
|
const_iterator begin() const { return instr_begin(); }
|
|
|
|
iterator end () { return instr_end(); }
|
|
|
|
const_iterator end () const { return instr_end(); }
|
2016-09-11 20:51:28 +02:00
|
|
|
reverse_iterator rbegin() {
|
|
|
|
return reverse_iterator::getAtBundleBegin(instr_rbegin());
|
|
|
|
}
|
ADT: Give ilist<T>::reverse_iterator a handle to the current node
Reverse iterators to doubly-linked lists can be simpler (and cheaper)
than std::reverse_iterator. Make it so.
In particular, change ilist<T>::reverse_iterator so that it is *never*
invalidated unless the node it references is deleted. This matches the
guarantees of ilist<T>::iterator.
(Note: MachineBasicBlock::iterator is *not* an ilist iterator, but a
MachineInstrBundleIterator<MachineInstr>. This commit does not change
MachineBasicBlock::reverse_iterator, but it does update
MachineBasicBlock::reverse_instr_iterator. See note at end of commit
message for details on bundle iterators.)
Given the list (with the Sentinel showing twice for simplicity):
[Sentinel] <-> A <-> B <-> [Sentinel]
the following is now true:
1. begin() represents A.
2. begin() holds the pointer for A.
3. end() represents [Sentinel].
4. end() holds the poitner for [Sentinel].
5. rbegin() represents B.
6. rbegin() holds the pointer for B.
7. rend() represents [Sentinel].
8. rend() holds the pointer for [Sentinel].
The changes are #6 and #8. Here are some properties from the old
scheme (which used std::reverse_iterator):
- rbegin() held the pointer for [Sentinel] and rend() held the pointer
for A;
- operator*() cost two dereferences instead of one;
- converting from a valid iterator to its valid reverse_iterator
involved a confusing increment; and
- "RI++->erase()" left RI invalid. The unintuitive replacement was
"RI->erase(), RE = end()".
With vector-like data structures these properties are hard to avoid
(since past-the-beginning is not a valid pointer), and don't impose a
real cost (since there's still only one dereference, and all iterators
are invalidated on erase). But with lists, this was a poor design.
Specifically, the following code (which obviously works with normal
iterators) now works with ilist::reverse_iterator as well:
for (auto RI = L.rbegin(), RE = L.rend(); RI != RE;)
fooThatMightRemoveArgFromList(*RI++);
Converting between iterator and reverse_iterator for the same node uses
the getReverse() function.
reverse_iterator iterator::getReverse();
iterator reverse_iterator::getReverse();
Why doesn't iterator <=> reverse_iterator conversion use constructors?
In order to catch and update old code, reverse_iterator does not even
have an explicit conversion from iterator. It wouldn't be safe because
there would be no reasonable way to catch all the bugs from the changed
semantic (see the changes at call sites that are part of this patch).
Old code used this API:
std::reverse_iterator::reverse_iterator(iterator);
iterator std::reverse_iterator::base();
Here's how to update from old code to new (that incorporates the
semantic change), assuming I is an ilist<>::iterator and RI is an
ilist<>::reverse_iterator:
[Old] ==> [New]
reverse_iterator(I) (--I).getReverse()
reverse_iterator(I) ++I.getReverse()
--reverse_iterator(I) I.getReverse()
reverse_iterator(++I) I.getReverse()
RI.base() (--RI).getReverse()
RI.base() ++RI.getReverse()
--RI.base() RI.getReverse()
(++RI).base() RI.getReverse()
delete &*RI, RE = end() delete &*RI++
RI->erase(), RE = end() RI++->erase()
=======================================
Note: bundle iterators are out of scope
=======================================
MachineBasicBlock::iterator, also known as
MachineInstrBundleIterator<MachineInstr>, is a wrapper to represent
MachineInstr bundles. The idea is that each operator++ takes you to the
beginning of the next bundle. Implementing a sane reverse iterator for
this is harder than ilist. Here are the options:
- Use std::reverse_iterator<MBB::i>. Store a handle to the beginning of
the next bundle. A call to operator*() runs a loop (usually
operator--() will be called 1 time, for unbundled instructions).
Increment/decrement just works. This is the status quo.
- Store a handle to the final node in the bundle. A call to operator*()
still runs a loop, but it iterates one time fewer (usually
operator--() will be called 0 times, for unbundled instructions).
Increment/decrement just works.
- Make the ilist_sentinel<MachineInstr> *always* store that it's the
sentinel (instead of just in asserts mode). Then the bundle iterator
can sniff the sentinel bit in operator++().
I initially tried implementing the end() option as part of this commit,
but updating iterator/reverse_iterator conversion call sites was
error-prone. I have a WIP series of patches that implements the final
option.
llvm-svn: 280032
2016-08-30 02:13:12 +02:00
|
|
|
const_reverse_iterator rbegin() const {
|
2016-09-11 20:51:28 +02:00
|
|
|
return const_reverse_iterator::getAtBundleBegin(instr_rbegin());
|
ADT: Give ilist<T>::reverse_iterator a handle to the current node
Reverse iterators to doubly-linked lists can be simpler (and cheaper)
than std::reverse_iterator. Make it so.
In particular, change ilist<T>::reverse_iterator so that it is *never*
invalidated unless the node it references is deleted. This matches the
guarantees of ilist<T>::iterator.
(Note: MachineBasicBlock::iterator is *not* an ilist iterator, but a
MachineInstrBundleIterator<MachineInstr>. This commit does not change
MachineBasicBlock::reverse_iterator, but it does update
MachineBasicBlock::reverse_instr_iterator. See note at end of commit
message for details on bundle iterators.)
Given the list (with the Sentinel showing twice for simplicity):
[Sentinel] <-> A <-> B <-> [Sentinel]
the following is now true:
1. begin() represents A.
2. begin() holds the pointer for A.
3. end() represents [Sentinel].
4. end() holds the poitner for [Sentinel].
5. rbegin() represents B.
6. rbegin() holds the pointer for B.
7. rend() represents [Sentinel].
8. rend() holds the pointer for [Sentinel].
The changes are #6 and #8. Here are some properties from the old
scheme (which used std::reverse_iterator):
- rbegin() held the pointer for [Sentinel] and rend() held the pointer
for A;
- operator*() cost two dereferences instead of one;
- converting from a valid iterator to its valid reverse_iterator
involved a confusing increment; and
- "RI++->erase()" left RI invalid. The unintuitive replacement was
"RI->erase(), RE = end()".
With vector-like data structures these properties are hard to avoid
(since past-the-beginning is not a valid pointer), and don't impose a
real cost (since there's still only one dereference, and all iterators
are invalidated on erase). But with lists, this was a poor design.
Specifically, the following code (which obviously works with normal
iterators) now works with ilist::reverse_iterator as well:
for (auto RI = L.rbegin(), RE = L.rend(); RI != RE;)
fooThatMightRemoveArgFromList(*RI++);
Converting between iterator and reverse_iterator for the same node uses
the getReverse() function.
reverse_iterator iterator::getReverse();
iterator reverse_iterator::getReverse();
Why doesn't iterator <=> reverse_iterator conversion use constructors?
In order to catch and update old code, reverse_iterator does not even
have an explicit conversion from iterator. It wouldn't be safe because
there would be no reasonable way to catch all the bugs from the changed
semantic (see the changes at call sites that are part of this patch).
Old code used this API:
std::reverse_iterator::reverse_iterator(iterator);
iterator std::reverse_iterator::base();
Here's how to update from old code to new (that incorporates the
semantic change), assuming I is an ilist<>::iterator and RI is an
ilist<>::reverse_iterator:
[Old] ==> [New]
reverse_iterator(I) (--I).getReverse()
reverse_iterator(I) ++I.getReverse()
--reverse_iterator(I) I.getReverse()
reverse_iterator(++I) I.getReverse()
RI.base() (--RI).getReverse()
RI.base() ++RI.getReverse()
--RI.base() RI.getReverse()
(++RI).base() RI.getReverse()
delete &*RI, RE = end() delete &*RI++
RI->erase(), RE = end() RI++->erase()
=======================================
Note: bundle iterators are out of scope
=======================================
MachineBasicBlock::iterator, also known as
MachineInstrBundleIterator<MachineInstr>, is a wrapper to represent
MachineInstr bundles. The idea is that each operator++ takes you to the
beginning of the next bundle. Implementing a sane reverse iterator for
this is harder than ilist. Here are the options:
- Use std::reverse_iterator<MBB::i>. Store a handle to the beginning of
the next bundle. A call to operator*() runs a loop (usually
operator--() will be called 1 time, for unbundled instructions).
Increment/decrement just works. This is the status quo.
- Store a handle to the final node in the bundle. A call to operator*()
still runs a loop, but it iterates one time fewer (usually
operator--() will be called 0 times, for unbundled instructions).
Increment/decrement just works.
- Make the ilist_sentinel<MachineInstr> *always* store that it's the
sentinel (instead of just in asserts mode). Then the bundle iterator
can sniff the sentinel bit in operator++().
I initially tried implementing the end() option as part of this commit,
but updating iterator/reverse_iterator conversion call sites was
error-prone. I have a WIP series of patches that implements the final
option.
llvm-svn: 280032
2016-08-30 02:13:12 +02:00
|
|
|
}
|
2016-09-11 20:51:28 +02:00
|
|
|
reverse_iterator rend() { return reverse_iterator(instr_rend()); }
|
ADT: Give ilist<T>::reverse_iterator a handle to the current node
Reverse iterators to doubly-linked lists can be simpler (and cheaper)
than std::reverse_iterator. Make it so.
In particular, change ilist<T>::reverse_iterator so that it is *never*
invalidated unless the node it references is deleted. This matches the
guarantees of ilist<T>::iterator.
(Note: MachineBasicBlock::iterator is *not* an ilist iterator, but a
MachineInstrBundleIterator<MachineInstr>. This commit does not change
MachineBasicBlock::reverse_iterator, but it does update
MachineBasicBlock::reverse_instr_iterator. See note at end of commit
message for details on bundle iterators.)
Given the list (with the Sentinel showing twice for simplicity):
[Sentinel] <-> A <-> B <-> [Sentinel]
the following is now true:
1. begin() represents A.
2. begin() holds the pointer for A.
3. end() represents [Sentinel].
4. end() holds the poitner for [Sentinel].
5. rbegin() represents B.
6. rbegin() holds the pointer for B.
7. rend() represents [Sentinel].
8. rend() holds the pointer for [Sentinel].
The changes are #6 and #8. Here are some properties from the old
scheme (which used std::reverse_iterator):
- rbegin() held the pointer for [Sentinel] and rend() held the pointer
for A;
- operator*() cost two dereferences instead of one;
- converting from a valid iterator to its valid reverse_iterator
involved a confusing increment; and
- "RI++->erase()" left RI invalid. The unintuitive replacement was
"RI->erase(), RE = end()".
With vector-like data structures these properties are hard to avoid
(since past-the-beginning is not a valid pointer), and don't impose a
real cost (since there's still only one dereference, and all iterators
are invalidated on erase). But with lists, this was a poor design.
Specifically, the following code (which obviously works with normal
iterators) now works with ilist::reverse_iterator as well:
for (auto RI = L.rbegin(), RE = L.rend(); RI != RE;)
fooThatMightRemoveArgFromList(*RI++);
Converting between iterator and reverse_iterator for the same node uses
the getReverse() function.
reverse_iterator iterator::getReverse();
iterator reverse_iterator::getReverse();
Why doesn't iterator <=> reverse_iterator conversion use constructors?
In order to catch and update old code, reverse_iterator does not even
have an explicit conversion from iterator. It wouldn't be safe because
there would be no reasonable way to catch all the bugs from the changed
semantic (see the changes at call sites that are part of this patch).
Old code used this API:
std::reverse_iterator::reverse_iterator(iterator);
iterator std::reverse_iterator::base();
Here's how to update from old code to new (that incorporates the
semantic change), assuming I is an ilist<>::iterator and RI is an
ilist<>::reverse_iterator:
[Old] ==> [New]
reverse_iterator(I) (--I).getReverse()
reverse_iterator(I) ++I.getReverse()
--reverse_iterator(I) I.getReverse()
reverse_iterator(++I) I.getReverse()
RI.base() (--RI).getReverse()
RI.base() ++RI.getReverse()
--RI.base() RI.getReverse()
(++RI).base() RI.getReverse()
delete &*RI, RE = end() delete &*RI++
RI->erase(), RE = end() RI++->erase()
=======================================
Note: bundle iterators are out of scope
=======================================
MachineBasicBlock::iterator, also known as
MachineInstrBundleIterator<MachineInstr>, is a wrapper to represent
MachineInstr bundles. The idea is that each operator++ takes you to the
beginning of the next bundle. Implementing a sane reverse iterator for
this is harder than ilist. Here are the options:
- Use std::reverse_iterator<MBB::i>. Store a handle to the beginning of
the next bundle. A call to operator*() runs a loop (usually
operator--() will be called 1 time, for unbundled instructions).
Increment/decrement just works. This is the status quo.
- Store a handle to the final node in the bundle. A call to operator*()
still runs a loop, but it iterates one time fewer (usually
operator--() will be called 0 times, for unbundled instructions).
Increment/decrement just works.
- Make the ilist_sentinel<MachineInstr> *always* store that it's the
sentinel (instead of just in asserts mode). Then the bundle iterator
can sniff the sentinel bit in operator++().
I initially tried implementing the end() option as part of this commit,
but updating iterator/reverse_iterator conversion call sites was
error-prone. I have a WIP series of patches that implements the final
option.
llvm-svn: 280032
2016-08-30 02:13:12 +02:00
|
|
|
const_reverse_iterator rend() const {
|
2016-09-11 20:51:28 +02:00
|
|
|
return const_reverse_iterator(instr_rend());
|
ADT: Give ilist<T>::reverse_iterator a handle to the current node
Reverse iterators to doubly-linked lists can be simpler (and cheaper)
than std::reverse_iterator. Make it so.
In particular, change ilist<T>::reverse_iterator so that it is *never*
invalidated unless the node it references is deleted. This matches the
guarantees of ilist<T>::iterator.
(Note: MachineBasicBlock::iterator is *not* an ilist iterator, but a
MachineInstrBundleIterator<MachineInstr>. This commit does not change
MachineBasicBlock::reverse_iterator, but it does update
MachineBasicBlock::reverse_instr_iterator. See note at end of commit
message for details on bundle iterators.)
Given the list (with the Sentinel showing twice for simplicity):
[Sentinel] <-> A <-> B <-> [Sentinel]
the following is now true:
1. begin() represents A.
2. begin() holds the pointer for A.
3. end() represents [Sentinel].
4. end() holds the poitner for [Sentinel].
5. rbegin() represents B.
6. rbegin() holds the pointer for B.
7. rend() represents [Sentinel].
8. rend() holds the pointer for [Sentinel].
The changes are #6 and #8. Here are some properties from the old
scheme (which used std::reverse_iterator):
- rbegin() held the pointer for [Sentinel] and rend() held the pointer
for A;
- operator*() cost two dereferences instead of one;
- converting from a valid iterator to its valid reverse_iterator
involved a confusing increment; and
- "RI++->erase()" left RI invalid. The unintuitive replacement was
"RI->erase(), RE = end()".
With vector-like data structures these properties are hard to avoid
(since past-the-beginning is not a valid pointer), and don't impose a
real cost (since there's still only one dereference, and all iterators
are invalidated on erase). But with lists, this was a poor design.
Specifically, the following code (which obviously works with normal
iterators) now works with ilist::reverse_iterator as well:
for (auto RI = L.rbegin(), RE = L.rend(); RI != RE;)
fooThatMightRemoveArgFromList(*RI++);
Converting between iterator and reverse_iterator for the same node uses
the getReverse() function.
reverse_iterator iterator::getReverse();
iterator reverse_iterator::getReverse();
Why doesn't iterator <=> reverse_iterator conversion use constructors?
In order to catch and update old code, reverse_iterator does not even
have an explicit conversion from iterator. It wouldn't be safe because
there would be no reasonable way to catch all the bugs from the changed
semantic (see the changes at call sites that are part of this patch).
Old code used this API:
std::reverse_iterator::reverse_iterator(iterator);
iterator std::reverse_iterator::base();
Here's how to update from old code to new (that incorporates the
semantic change), assuming I is an ilist<>::iterator and RI is an
ilist<>::reverse_iterator:
[Old] ==> [New]
reverse_iterator(I) (--I).getReverse()
reverse_iterator(I) ++I.getReverse()
--reverse_iterator(I) I.getReverse()
reverse_iterator(++I) I.getReverse()
RI.base() (--RI).getReverse()
RI.base() ++RI.getReverse()
--RI.base() RI.getReverse()
(++RI).base() RI.getReverse()
delete &*RI, RE = end() delete &*RI++
RI->erase(), RE = end() RI++->erase()
=======================================
Note: bundle iterators are out of scope
=======================================
MachineBasicBlock::iterator, also known as
MachineInstrBundleIterator<MachineInstr>, is a wrapper to represent
MachineInstr bundles. The idea is that each operator++ takes you to the
beginning of the next bundle. Implementing a sane reverse iterator for
this is harder than ilist. Here are the options:
- Use std::reverse_iterator<MBB::i>. Store a handle to the beginning of
the next bundle. A call to operator*() runs a loop (usually
operator--() will be called 1 time, for unbundled instructions).
Increment/decrement just works. This is the status quo.
- Store a handle to the final node in the bundle. A call to operator*()
still runs a loop, but it iterates one time fewer (usually
operator--() will be called 0 times, for unbundled instructions).
Increment/decrement just works.
- Make the ilist_sentinel<MachineInstr> *always* store that it's the
sentinel (instead of just in asserts mode). Then the bundle iterator
can sniff the sentinel bit in operator++().
I initially tried implementing the end() option as part of this commit,
but updating iterator/reverse_iterator conversion call sites was
error-prone. I have a WIP series of patches that implements the final
option.
llvm-svn: 280032
2016-08-30 02:13:12 +02:00
|
|
|
}
|
2002-07-09 00:40:34 +02:00
|
|
|
|
ADT: Avoid relying on UB in ilist_node::getNextNode()
Re-implement `ilist_node::getNextNode()` and `getPrevNode()` without
relying on the sentinel having a "next" pointer. Instead, get access to
the owning list and compare against the `begin()` and `end()` iterators.
This only works when the node *can* get access to the owning list. The
new support is in `ilist_node_with_parent<>`, and any class `Ty`
inheriting from `ilist_node<NodeTy>` that wants `getNextNode()` and/or
`getPrevNode()` should inherit from
`ilist_node_with_parent<NodeTy, ParentTy>` instead. The requirements:
- `NodeTy` must have a `getParent()` function that returns the parent.
- `ParentTy` must have a `getSublistAccess()` static that, given a(n
ignored) `NodeTy*` (to determine which list), returns a member field
pointer to the appropriate `ilist<>`.
This isn't the cleanest way to get access to the owning list, but it
leverages the API already used in the IR hierarchy (see, e.g.,
`Instruction::getSublistAccess()`).
If anyone feels like ripping out the calls to `getNextNode()` and
`getPrevNode()` and replacing with direct iterator logic, they can also
remove the access function, etc., but as an incremental step, I'm
maintaining the API where it's currently used in tree.
If these requirements are *not* met, call sites with access to the ilist
can call `iplist<NodeTy>::getNextNode(NodeTy*)` directly, as in
ilistTest.cpp.
Why rewrite this?
The old code was broken, calling `getNext()` on a sentinel that possibly
didn't have a "next" pointer at all! The new code avoids that
particular flavour of UB (see the commit message for r252538 for more
details about the "lucky" memory layout that made this function so
interesting).
There's still some UB here: the end iterator gets downcast to `NodeTy*`,
even when it's a sentinel (which is typically
`ilist_half_node<NodeTy*>`). I'll tackle that in follow-up commits.
See this llvm-dev thread for more details:
http://lists.llvm.org/pipermail/llvm-dev/2015-October/091115.html
What's the danger?
There might be some code that relies on `getNextNode()` or
`getPrevNode()` *never* returning `nullptr` -- i.e., that relies on them
being broken when the sentinel is an `ilist_half_node<NodeTy>`. I tried
to root out those cases with the audits I did leading up to r252380, but
it's possible I missed one or two. I hope not.
(If (1) you have out-of-tree code, (2) you've reverted r252380
temporarily, and (3) you get some weird crashes with this commit, then I
recommend un-reverting r252380 and auditing the compile errors looking
for "strange" implicit conversions.)
llvm-svn: 252694
2015-11-11 03:26:42 +01:00
|
|
|
/// Support for MachineInstr::getNextNode().
|
|
|
|
static Instructions MachineBasicBlock::*getSublistAccess(MachineInstr *) {
|
|
|
|
return &MachineBasicBlock::Insts;
|
|
|
|
}
|
|
|
|
|
2014-04-17 00:37:58 +02:00
|
|
|
inline iterator_range<iterator> terminators() {
|
2015-12-06 06:08:07 +01:00
|
|
|
return make_range(getFirstTerminator(), end());
|
2014-04-17 00:37:58 +02:00
|
|
|
}
|
|
|
|
inline iterator_range<const_iterator> terminators() const {
|
2015-12-06 06:08:07 +01:00
|
|
|
return make_range(getFirstTerminator(), end());
|
2014-04-17 00:37:58 +02:00
|
|
|
}
|
2011-12-06 23:12:01 +01:00
|
|
|
|
2018-01-04 03:58:15 +01:00
|
|
|
/// Returns a range that iterates over the phis in the basic block.
|
|
|
|
inline iterator_range<iterator> phis() {
|
|
|
|
return make_range(begin(), getFirstNonPHI());
|
|
|
|
}
|
|
|
|
inline iterator_range<const_iterator> phis() const {
|
|
|
|
return const_cast<MachineBasicBlock *>(this)->phis();
|
|
|
|
}
|
|
|
|
|
2004-04-28 04:16:33 +02:00
|
|
|
// Machine-CFG iterators
|
2017-05-25 01:10:29 +02:00
|
|
|
using pred_iterator = std::vector<MachineBasicBlock *>::iterator;
|
|
|
|
using const_pred_iterator = std::vector<MachineBasicBlock *>::const_iterator;
|
|
|
|
using succ_iterator = std::vector<MachineBasicBlock *>::iterator;
|
|
|
|
using const_succ_iterator = std::vector<MachineBasicBlock *>::const_iterator;
|
|
|
|
using pred_reverse_iterator =
|
|
|
|
std::vector<MachineBasicBlock *>::reverse_iterator;
|
|
|
|
using const_pred_reverse_iterator =
|
|
|
|
std::vector<MachineBasicBlock *>::const_reverse_iterator;
|
|
|
|
using succ_reverse_iterator =
|
|
|
|
std::vector<MachineBasicBlock *>::reverse_iterator;
|
|
|
|
using const_succ_reverse_iterator =
|
|
|
|
std::vector<MachineBasicBlock *>::const_reverse_iterator;
|
2006-10-21 08:50:05 +02:00
|
|
|
pred_iterator pred_begin() { return Predecessors.begin(); }
|
|
|
|
const_pred_iterator pred_begin() const { return Predecessors.begin(); }
|
|
|
|
pred_iterator pred_end() { return Predecessors.end(); }
|
|
|
|
const_pred_iterator pred_end() const { return Predecessors.end(); }
|
2007-05-08 20:55:03 +02:00
|
|
|
pred_reverse_iterator pred_rbegin()
|
|
|
|
{ return Predecessors.rbegin();}
|
|
|
|
const_pred_reverse_iterator pred_rbegin() const
|
|
|
|
{ return Predecessors.rbegin();}
|
|
|
|
pred_reverse_iterator pred_rend()
|
|
|
|
{ return Predecessors.rend(); }
|
|
|
|
const_pred_reverse_iterator pred_rend() const
|
|
|
|
{ return Predecessors.rend(); }
|
2008-05-05 20:30:58 +02:00
|
|
|
unsigned pred_size() const {
|
|
|
|
return (unsigned)Predecessors.size();
|
|
|
|
}
|
2006-10-21 08:50:05 +02:00
|
|
|
bool pred_empty() const { return Predecessors.empty(); }
|
|
|
|
succ_iterator succ_begin() { return Successors.begin(); }
|
|
|
|
const_succ_iterator succ_begin() const { return Successors.begin(); }
|
|
|
|
succ_iterator succ_end() { return Successors.end(); }
|
|
|
|
const_succ_iterator succ_end() const { return Successors.end(); }
|
2007-05-08 20:55:03 +02:00
|
|
|
succ_reverse_iterator succ_rbegin()
|
|
|
|
{ return Successors.rbegin(); }
|
|
|
|
const_succ_reverse_iterator succ_rbegin() const
|
|
|
|
{ return Successors.rbegin(); }
|
|
|
|
succ_reverse_iterator succ_rend()
|
|
|
|
{ return Successors.rend(); }
|
|
|
|
const_succ_reverse_iterator succ_rend() const
|
|
|
|
{ return Successors.rend(); }
|
2008-05-05 20:30:58 +02:00
|
|
|
unsigned succ_size() const {
|
|
|
|
return (unsigned)Successors.size();
|
|
|
|
}
|
2006-10-21 08:50:05 +02:00
|
|
|
bool succ_empty() const { return Successors.empty(); }
|
2004-04-28 04:16:33 +02:00
|
|
|
|
2014-04-04 04:10:59 +02:00
|
|
|
inline iterator_range<pred_iterator> predecessors() {
|
2015-12-06 06:08:07 +01:00
|
|
|
return make_range(pred_begin(), pred_end());
|
2014-04-04 04:10:59 +02:00
|
|
|
}
|
2014-04-04 19:36:55 +02:00
|
|
|
inline iterator_range<const_pred_iterator> predecessors() const {
|
2015-12-06 06:08:07 +01:00
|
|
|
return make_range(pred_begin(), pred_end());
|
2014-04-04 04:10:59 +02:00
|
|
|
}
|
2014-04-04 04:14:38 +02:00
|
|
|
inline iterator_range<succ_iterator> successors() {
|
2015-12-06 06:08:07 +01:00
|
|
|
return make_range(succ_begin(), succ_end());
|
2014-04-04 04:10:59 +02:00
|
|
|
}
|
2014-04-04 19:36:55 +02:00
|
|
|
inline iterator_range<const_succ_iterator> successors() const {
|
2015-12-06 06:08:07 +01:00
|
|
|
return make_range(succ_begin(), succ_end());
|
2014-04-04 04:10:59 +02:00
|
|
|
}
|
|
|
|
|
2007-02-10 03:38:19 +01:00
|
|
|
// LiveIn management methods.
|
|
|
|
|
2015-05-22 10:11:26 +02:00
|
|
|
/// Adds the specified register as a live in. Note that it is an error to add
|
|
|
|
/// the same register to the same set more than once unless the intention is
|
|
|
|
/// to call sortUniqueLiveIns after all registers are added.
|
2016-12-15 15:36:06 +01:00
|
|
|
void addLiveIn(MCPhysReg PhysReg,
|
|
|
|
LaneBitmask LaneMask = LaneBitmask::getAll()) {
|
2015-09-09 20:08:03 +02:00
|
|
|
LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask));
|
|
|
|
}
|
|
|
|
void addLiveIn(const RegisterMaskPair &RegMaskPair) {
|
|
|
|
LiveIns.push_back(RegMaskPair);
|
|
|
|
}
|
2015-05-22 10:11:26 +02:00
|
|
|
|
|
|
|
/// Sorts and uniques the LiveIns vector. It can be significantly faster to do
|
|
|
|
/// this than repeatedly calling isLiveIn before calling addLiveIn for every
|
|
|
|
/// LiveIn insertion.
|
2015-09-09 20:08:03 +02:00
|
|
|
void sortUniqueLiveIns();
|
2007-02-10 03:38:19 +01:00
|
|
|
|
2016-12-17 00:55:37 +01:00
|
|
|
/// Clear live in list.
|
|
|
|
void clearLiveIns();
|
|
|
|
|
2013-07-04 01:56:20 +02:00
|
|
|
/// 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.
|
2015-08-26 00:05:55 +02:00
|
|
|
unsigned addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC);
|
2013-07-04 01:56:20 +02:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Remove the specified register from the live in set.
|
2016-12-15 15:36:06 +01:00
|
|
|
void removeLiveIn(MCPhysReg Reg,
|
|
|
|
LaneBitmask LaneMask = LaneBitmask::getAll());
|
2007-02-19 22:49:54 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return true if the specified register is in the live in set.
|
2016-12-15 15:36:06 +01:00
|
|
|
bool isLiveIn(MCPhysReg Reg,
|
|
|
|
LaneBitmask LaneMask = LaneBitmask::getAll()) const;
|
2008-04-24 11:06:33 +02:00
|
|
|
|
2007-02-10 03:38:19 +01:00
|
|
|
// Iteration support for live in sets. These sets are kept in sorted
|
|
|
|
// order by their register number.
|
2017-05-25 01:10:29 +02:00
|
|
|
using livein_iterator = LiveInVector::const_iterator;
|
2017-01-07 01:46:30 +01:00
|
|
|
#ifndef NDEBUG
|
|
|
|
/// Unlike livein_begin, this method does not check that the liveness
|
|
|
|
/// information is accurate. Still for debug purposes it may be useful
|
|
|
|
/// to have iterators that won't assert if the liveness information
|
|
|
|
/// is not current.
|
|
|
|
livein_iterator livein_begin_dbg() const { return LiveIns.begin(); }
|
|
|
|
iterator_range<livein_iterator> liveins_dbg() const {
|
|
|
|
return make_range(livein_begin_dbg(), livein_end());
|
|
|
|
}
|
|
|
|
#endif
|
2017-01-05 21:01:19 +01:00
|
|
|
livein_iterator livein_begin() const;
|
2015-07-29 17:57:49 +02:00
|
|
|
livein_iterator livein_end() const { return LiveIns.end(); }
|
2007-02-10 03:38:19 +01:00
|
|
|
bool livein_empty() const { return LiveIns.empty(); }
|
2015-08-25 00:59:52 +02:00
|
|
|
iterator_range<livein_iterator> liveins() const {
|
|
|
|
return make_range(livein_begin(), livein_end());
|
|
|
|
}
|
2007-02-10 03:38:19 +01:00
|
|
|
|
2017-05-31 22:30:22 +02:00
|
|
|
/// Remove entry from the livein set and return iterator to the next.
|
|
|
|
livein_iterator removeLiveIn(livein_iterator I);
|
|
|
|
|
2015-11-06 18:06:38 +01:00
|
|
|
/// Get the clobber mask for the start of this basic block. Funclets use this
|
|
|
|
/// to prevent register allocation across funclet transitions.
|
|
|
|
const uint32_t *getBeginClobberMask(const TargetRegisterInfo *TRI) const;
|
|
|
|
|
|
|
|
/// Get the clobber mask for the end of the basic block.
|
|
|
|
/// \see getBeginClobberMask()
|
|
|
|
const uint32_t *getEndClobberMask(const TargetRegisterInfo *TRI) const;
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return alignment of the basic block. The alignment is specified as
|
|
|
|
/// log2(bytes).
|
2008-02-28 01:43:03 +01:00
|
|
|
unsigned getAlignment() const { return Alignment; }
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Set alignment of the basic block. The alignment is specified as
|
|
|
|
/// log2(bytes).
|
2008-02-28 01:43:03 +01:00
|
|
|
void setAlignment(unsigned Align) { Alignment = Align; }
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Returns true if the block is a landing pad. That is this basic block is
|
|
|
|
/// entered via an exception handler.
|
2015-08-28 01:27:47 +02:00
|
|
|
bool isEHPad() const { return IsEHPad; }
|
2007-02-21 23:39:52 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Indicates the block is a landing pad. That is this basic block is entered
|
|
|
|
/// via an exception handler.
|
2015-08-28 01:27:47 +02:00
|
|
|
void setIsEHPad(bool V = true) { IsEHPad = V; }
|
2007-02-21 23:39:52 +01:00
|
|
|
|
2015-09-17 19:19:40 +02:00
|
|
|
bool hasEHPadSuccessor() const;
|
|
|
|
|
[WebAssembly] Add functions for EHScopes
Summary:
There are functions using the term 'funclet' to refer to both
1. an EH scopes, the structure of BBs that starts with
catchpad/cleanuppad and ends with catchret/cleanupret, and
2. a small function that gets outlined in AsmPrinter, which is the
original meaning of 'funclet'.
So far the two have been the same thing; EH scopes are always outlined
in AsmPrinter as funclets at the end of the compilation pipeline. But
now wasm also uses scope-based EH but does not outline those, so we now
need to correctly distinguish those two use cases in functions.
This patch splits `MachineBasicBlock::isFuncletEntry` into
`isFuncletEntry` and `isEHScopeEntry`, and
`MachineFunction::hasFunclets` into `hasFunclets` and `hasEHScopes`, in
order to distinguish the two different use cases. And this also changes
some uses of the term 'funclet' to 'scope' in `getFuncletMembership` and
change the function name to `getEHScopeMembership` because this function
is not about outlined funclets but about EH scope memberships.
This change is in the same vein as D45559.
Reviewers: majnemer, dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D47005
llvm-svn: 333045
2018-05-23 02:32:46 +02:00
|
|
|
/// Returns true if this is the entry block of an EH scope, i.e., the block
|
|
|
|
/// that used to have a catchpad or cleanuppad instruction in the LLVM IR.
|
|
|
|
bool isEHScopeEntry() const { return IsEHScopeEntry; }
|
|
|
|
|
|
|
|
/// Indicates if this is the entry block of an EH scope, i.e., the block that
|
|
|
|
/// that used to have a catchpad or cleanuppad instruction in the LLVM IR.
|
|
|
|
void setIsEHScopeEntry(bool V = true) { IsEHScopeEntry = V; }
|
|
|
|
|
2015-08-28 01:27:47 +02:00
|
|
|
/// Returns true if this is the entry block of an EH funclet.
|
|
|
|
bool isEHFuncletEntry() const { return IsEHFuncletEntry; }
|
|
|
|
|
|
|
|
/// Indicates if this is the entry block of an EH funclet.
|
|
|
|
void setIsEHFuncletEntry(bool V = true) { IsEHFuncletEntry = V; }
|
|
|
|
|
2015-09-29 22:12:33 +02:00
|
|
|
/// Returns true if this is the entry block of a cleanup funclet.
|
|
|
|
bool isCleanupFuncletEntry() const { return IsCleanupFuncletEntry; }
|
|
|
|
|
|
|
|
/// Indicates if this is the entry block of a cleanup funclet.
|
|
|
|
void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
|
|
|
|
|
2017-06-23 01:27:16 +02:00
|
|
|
/// Returns true if it is legal to hoist instructions into this block.
|
|
|
|
bool isLegalToHoistInto() const;
|
|
|
|
|
2006-10-24 01:35:35 +02:00
|
|
|
// Code Layout methods.
|
2012-01-31 20:47:32 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Move 'this' block before or after the specified block. This only moves
|
|
|
|
/// the block, it does not modify the CFG or adjust potential fall-throughs at
|
|
|
|
/// the end of the block.
|
2006-10-24 01:35:35 +02:00
|
|
|
void moveBefore(MachineBasicBlock *NewAfter);
|
|
|
|
void moveAfter(MachineBasicBlock *NewBefore);
|
2009-11-12 04:55:33 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// 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.
|
2009-11-12 04:55:33 +01:00
|
|
|
void updateTerminator();
|
|
|
|
|
2004-04-28 04:16:33 +02:00
|
|
|
// Machine-CFG mutators
|
2011-06-16 22:22:37 +02:00
|
|
|
|
2015-11-04 22:37:58 +01:00
|
|
|
/// Add Succ as a successor of this MachineBasicBlock. The Predecessors list
|
|
|
|
/// of Succ is automatically updated. PROB parameter is stored in
|
2015-12-01 06:29:22 +01:00
|
|
|
/// Probabilities list. The default probability is set as unknown. Mixing
|
|
|
|
/// known and unknown probabilities in successor list is not allowed. When all
|
|
|
|
/// successors have unknown probabilities, 1 / N is returned as the
|
|
|
|
/// probability for each successor, where N is the number of successors.
|
2015-11-04 22:37:58 +01:00
|
|
|
///
|
|
|
|
/// Note that duplicate Machine CFG edges are not allowed.
|
2015-12-01 06:29:22 +01:00
|
|
|
void addSuccessor(MachineBasicBlock *Succ,
|
|
|
|
BranchProbability Prob = BranchProbability::getUnknown());
|
2015-11-04 22:37:58 +01:00
|
|
|
|
|
|
|
/// Add Succ as a successor of this MachineBasicBlock. The Predecessors list
|
|
|
|
/// of Succ is automatically updated. The probability is not provided because
|
|
|
|
/// BPI is not available (e.g. -O0 is used), in which case edge probabilities
|
|
|
|
/// won't be used. Using this interface can save some space.
|
|
|
|
void addSuccessorWithoutProb(MachineBasicBlock *Succ);
|
|
|
|
|
|
|
|
/// Set successor probability of a given iterator.
|
|
|
|
void setSuccProbability(succ_iterator I, BranchProbability Prob);
|
|
|
|
|
|
|
|
/// Normalize probabilities of all successors so that the sum of them becomes
|
2015-12-13 10:26:17 +01:00
|
|
|
/// one. This is usually done when the current update on this MBB is done, and
|
|
|
|
/// the sum of its successors' probabilities is not guaranteed to be one. The
|
|
|
|
/// user is responsible for the correct use of this function.
|
|
|
|
/// MBB::removeSuccessor() has an option to do this automatically.
|
2015-11-04 22:37:58 +01:00
|
|
|
void normalizeSuccProbs() {
|
2015-11-18 02:03:19 +01:00
|
|
|
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
|
2015-11-04 22:37:58 +01:00
|
|
|
}
|
|
|
|
|
2015-12-13 10:26:17 +01:00
|
|
|
/// Validate successors' probabilities and check if the sum of them is
|
|
|
|
/// approximate one. This only works in DEBUG mode.
|
|
|
|
void validateSuccProbs() const;
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Remove successor from the successors list of this MachineBasicBlock. The
|
2015-09-29 21:46:09 +02:00
|
|
|
/// Predecessors list of Succ is automatically updated.
|
2015-12-13 10:26:17 +01:00
|
|
|
/// If NormalizeSuccProbs is true, then normalize successors' probabilities
|
|
|
|
/// after the successor is removed.
|
|
|
|
void removeSuccessor(MachineBasicBlock *Succ,
|
|
|
|
bool NormalizeSuccProbs = false);
|
2004-07-31 03:59:11 +02:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Remove specified successor from the successors list of this
|
2015-09-29 21:46:09 +02:00
|
|
|
/// MachineBasicBlock. The Predecessors list of Succ is automatically updated.
|
2015-12-13 10:26:17 +01:00
|
|
|
/// If NormalizeSuccProbs is true, then normalize successors' probabilities
|
|
|
|
/// after the successor is removed.
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return the iterator to the element after the one removed.
|
2015-12-13 10:26:17 +01:00
|
|
|
succ_iterator removeSuccessor(succ_iterator I,
|
|
|
|
bool NormalizeSuccProbs = false);
|
2011-06-16 22:22:37 +02:00
|
|
|
|
2015-12-01 06:29:22 +01:00
|
|
|
/// Replace successor OLD with NEW and update probability info.
|
2011-06-16 22:22:37 +02:00
|
|
|
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New);
|
|
|
|
|
[x86] Introduce a pass to begin more systematically fixing PR36028 and similar issues.
The key idea is to lower COPY nodes populating EFLAGS by scanning the
uses of EFLAGS and introducing dedicated code to preserve the necessary
state in a GPR. In the vast majority of cases, these uses are cmovCC and
jCC instructions. For such cases, we can very easily save and restore
the necessary information by simply inserting a setCC into a GPR where
the original flags are live, and then testing that GPR directly to feed
the cmov or conditional branch.
However, things are a bit more tricky if arithmetic is using the flags.
This patch handles the vast majority of cases that seem to come up in
practice: adc, adcx, adox, rcl, and rcr; all without taking advantage of
partially preserved EFLAGS as LLVM doesn't currently model that at all.
There are a large number of operations that techinaclly observe EFLAGS
currently but shouldn't in this case -- they typically are using DF.
Currently, they will not be handled by this approach. However, I have
never seen this issue come up in practice. It is already pretty rare to
have these patterns come up in practical code with LLVM. I had to resort
to writing MIR tests to cover most of the logic in this pass already.
I suspect even with its current amount of coverage of arithmetic users
of EFLAGS it will be a significant improvement over the current use of
pushf/popf. It will also produce substantially faster code in most of
the common patterns.
This patch also removes all of the old lowering for EFLAGS copies, and
the hack that forced us to use a frame pointer when EFLAGS copies were
found anywhere in a function so that the dynamic stack adjustment wasn't
a problem. None of this is needed as we now lower all of these copies
directly in MI and without require stack adjustments.
Lots of thanks to Reid who came up with several aspects of this
approach, and Craig who helped me work out a couple of things tripping
me up while working on this.
Differential Revision: https://reviews.llvm.org/D45146
llvm-svn: 329657
2018-04-10 03:41:17 +02:00
|
|
|
/// Copy a successor (and any probability info) from original block to this
|
|
|
|
/// block's. Uses an iterator into the original blocks successors.
|
|
|
|
///
|
|
|
|
/// This is useful when doing a partial clone of successors. Afterward, the
|
|
|
|
/// probabilities may need to be normalized.
|
|
|
|
void copySuccessor(MachineBasicBlock *Orig, succ_iterator I);
|
|
|
|
|
2018-07-13 13:13:58 +02:00
|
|
|
/// Split the old successor into old plus new and updates the probability
|
|
|
|
/// info.
|
|
|
|
void splitSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New,
|
|
|
|
bool NormalizeSuccProbs = false);
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Transfers all the successors from MBB to this machine basic block (i.e.,
|
2015-09-29 21:46:09 +02:00
|
|
|
/// copies all the successors FromMBB and remove all the successors from
|
|
|
|
/// FromMBB).
|
|
|
|
void transferSuccessors(MachineBasicBlock *FromMBB);
|
2010-07-06 22:24:04 +02:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Transfers all the successors, as in transferSuccessors, and update PHI
|
2015-09-29 21:46:09 +02:00
|
|
|
/// operands in the successor blocks which refer to FromMBB to refer to this.
|
|
|
|
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB);
|
2012-01-31 20:47:32 +01:00
|
|
|
|
2015-11-04 22:37:58 +01:00
|
|
|
/// Return true if any of the successors have probabilities attached to them.
|
|
|
|
bool hasSuccessorProbabilities() const { return !Probs.empty(); }
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return true if the specified MBB is a predecessor of this block.
|
2012-07-30 19:36:47 +02:00
|
|
|
bool isPredecessor(const MachineBasicBlock *MBB) const;
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return true if the specified MBB is a successor of this block.
|
2009-03-30 22:06:29 +02:00
|
|
|
bool isSuccessor(const MachineBasicBlock *MBB) const;
|
2004-04-28 04:16:33 +02:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return true if the specified MBB will be emitted immediately after this
|
|
|
|
/// block, such that if this block exits by falling through, control will
|
|
|
|
/// transfer to the specified MBB. Note that MBB need not be a successor at
|
|
|
|
/// all, for example if this block ends with an unconditional branch to some
|
|
|
|
/// other block.
|
2009-03-30 22:06:29 +02:00
|
|
|
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const;
|
2008-10-03 00:09:09 +02:00
|
|
|
|
2017-03-31 17:55:37 +02:00
|
|
|
/// Return the fallthrough block if the block can implicitly
|
|
|
|
/// transfer control to the block after it by falling off the end of
|
|
|
|
/// it. This should return null if it can reach the block after
|
|
|
|
/// it, but it uses an explicit branch to do so (e.g., a table
|
|
|
|
/// jump). Non-null return is a conservative answer.
|
|
|
|
MachineBasicBlock *getFallThrough();
|
|
|
|
|
|
|
|
/// Return true if the block can implicitly transfer control to the
|
|
|
|
/// block after it by falling off the end of it. This should return
|
|
|
|
/// false if it can reach the block after it, but it uses an
|
|
|
|
/// explicit branch to do so (e.g., a table jump). True is a
|
|
|
|
/// conservative answer.
|
2009-11-26 01:32:21 +01:00
|
|
|
bool canFallThrough();
|
|
|
|
|
2013-09-28 15:42:22 +02:00
|
|
|
/// Returns a pointer to the first instruction in this block that is not a
|
|
|
|
/// PHINode instruction. When adding instructions to the beginning of the
|
2010-07-07 16:33:51 +02:00
|
|
|
/// basic block, they should be added before the returned value, not before
|
|
|
|
/// the first instruction, which might be PHI.
|
|
|
|
/// Returns end() is there's no non-PHI instruction.
|
|
|
|
iterator getFirstNonPHI();
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return the first instruction in MBB after I that is not a PHI or a label.
|
2016-09-16 16:07:29 +02:00
|
|
|
/// This is the correct point to insert lowered copies at the beginning of a
|
|
|
|
/// basic block that must be before any debugging information.
|
2010-10-30 03:26:14 +02:00
|
|
|
iterator SkipPHIsAndLabels(iterator I);
|
|
|
|
|
2016-09-16 16:07:29 +02:00
|
|
|
/// Return the first instruction in MBB after I that is not a PHI, label or
|
|
|
|
/// debug. This is the correct point to insert copies at the beginning of a
|
|
|
|
/// basic block.
|
|
|
|
iterator SkipPHIsLabelsAndDebug(iterator I);
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Returns an iterator to the first terminator instruction of this basic
|
|
|
|
/// block. If a terminator does not exist, it returns end().
|
2004-02-23 19:14:48 +01:00
|
|
|
iterator getFirstTerminator();
|
2015-06-23 16:47:18 +02:00
|
|
|
const_iterator getFirstTerminator() const {
|
|
|
|
return const_cast<MachineBasicBlock *>(this)->getFirstTerminator();
|
|
|
|
}
|
2004-02-23 19:14:48 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Same getFirstTerminator but it ignores bundles and return an
|
|
|
|
/// instr_iterator instead.
|
2011-12-14 03:11:42 +01:00
|
|
|
instr_iterator getFirstInstrTerminator();
|
2011-04-05 06:20:27 +02:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Returns an iterator to the first non-debug instruction in the basic block,
|
|
|
|
/// or end().
|
2015-06-23 16:47:29 +02:00
|
|
|
iterator getFirstNonDebugInstr();
|
|
|
|
const_iterator getFirstNonDebugInstr() const {
|
|
|
|
return const_cast<MachineBasicBlock *>(this)->getFirstNonDebugInstr();
|
|
|
|
}
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Returns an iterator to the last non-debug instruction in the basic block,
|
|
|
|
/// or end().
|
2011-01-13 22:28:52 +01:00
|
|
|
iterator getLastNonDebugInstr();
|
2015-06-23 16:47:18 +02:00
|
|
|
const_iterator getLastNonDebugInstr() const {
|
|
|
|
return const_cast<MachineBasicBlock *>(this)->getLastNonDebugInstr();
|
|
|
|
}
|
2011-03-26 03:19:36 +01:00
|
|
|
|
2015-11-06 18:06:38 +01:00
|
|
|
/// Convenience function that returns true if the block ends in a return
|
|
|
|
/// instruction.
|
2015-09-25 23:25:19 +02:00
|
|
|
bool isReturnBlock() const {
|
|
|
|
return !empty() && back().isReturn();
|
|
|
|
}
|
|
|
|
|
2018-08-21 21:44:11 +02:00
|
|
|
/// Convenience function that returns true if the bock ends in a EH scope
|
|
|
|
/// return instruction.
|
|
|
|
bool isEHScopeReturnBlock() const {
|
|
|
|
return !empty() && back().isEHScopeReturn();
|
|
|
|
}
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Split the critical edge from this block to the given successor block, and
|
|
|
|
/// return the newly created block, or null if splitting is not possible.
|
2010-06-22 19:25:57 +02:00
|
|
|
///
|
|
|
|
/// This function updates LiveVariables, MachineDominatorTree, and
|
|
|
|
/// MachineLoopInfo, as applicable.
|
2016-04-21 23:01:13 +02:00
|
|
|
MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P);
|
2010-06-22 19:25:57 +02:00
|
|
|
|
2016-04-21 22:46:27 +02:00
|
|
|
/// Check if the edge between this block and the given successor \p
|
|
|
|
/// Succ, can be split. If this returns true a subsequent call to
|
|
|
|
/// SplitCriticalEdge is guaranteed to return a valid basic block if
|
2018-01-24 11:33:39 +01:00
|
|
|
/// no changes occurred in the meantime.
|
2016-04-21 22:46:27 +02:00
|
|
|
bool canSplitCriticalEdge(const MachineBasicBlock *Succ) const;
|
|
|
|
|
2004-06-08 20:52:47 +02:00
|
|
|
void pop_front() { Insts.pop_front(); }
|
2004-07-31 11:59:04 +02:00
|
|
|
void pop_back() { Insts.pop_back(); }
|
2002-07-09 00:40:34 +02:00
|
|
|
void push_back(MachineInstr *MI) { Insts.push_back(MI); }
|
2011-12-06 23:12:01 +01:00
|
|
|
|
2012-12-18 18:54:53 +01:00
|
|
|
/// Insert MI into the instruction list before I, possibly inside a bundle.
|
|
|
|
///
|
|
|
|
/// If the insertion point is inside a bundle, MI will be added to the bundle,
|
|
|
|
/// otherwise MI will not be added to any bundle. That means this function
|
|
|
|
/// alone can't be used to prepend or append instructions to bundles. See
|
|
|
|
/// MIBundleBuilder::insert() for a more reliable way of doing that.
|
|
|
|
instr_iterator insert(instr_iterator I, MachineInstr *M);
|
2002-07-09 00:40:34 +02:00
|
|
|
|
2012-12-18 18:54:53 +01:00
|
|
|
/// Insert a range of instructions into the instruction list before I.
|
2011-12-06 23:12:01 +01:00
|
|
|
template<typename IT>
|
|
|
|
void insert(iterator I, IT S, IT E) {
|
2014-11-14 01:34:59 +01:00
|
|
|
assert((I == end() || I->getParent() == this) &&
|
|
|
|
"iterator points outside of basic block");
|
2016-02-22 22:30:15 +01:00
|
|
|
Insts.insert(I.getInstrIterator(), S, E);
|
2011-12-06 23:12:01 +01:00
|
|
|
}
|
2012-12-18 18:54:53 +01:00
|
|
|
|
|
|
|
/// Insert MI into the instruction list before I.
|
|
|
|
iterator insert(iterator I, MachineInstr *MI) {
|
2014-11-14 01:34:59 +01:00
|
|
|
assert((I == end() || I->getParent() == this) &&
|
|
|
|
"iterator points outside of basic block");
|
2012-12-18 18:54:53 +01:00
|
|
|
assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
|
|
|
|
"Cannot insert instruction with bundle flags");
|
2016-02-22 22:30:15 +01:00
|
|
|
return Insts.insert(I.getInstrIterator(), MI);
|
2011-12-06 23:12:01 +01:00
|
|
|
}
|
2012-12-18 18:54:53 +01:00
|
|
|
|
|
|
|
/// Insert MI into the instruction list after I.
|
|
|
|
iterator insertAfter(iterator I, MachineInstr *MI) {
|
2014-11-14 01:34:59 +01:00
|
|
|
assert((I == end() || I->getParent() == this) &&
|
|
|
|
"iterator points outside of basic block");
|
2012-12-18 18:54:53 +01:00
|
|
|
assert(!MI->isBundledWithPred() && !MI->isBundledWithSucc() &&
|
|
|
|
"Cannot insert instruction with bundle flags");
|
2016-02-22 22:30:15 +01:00
|
|
|
return Insts.insertAfter(I.getInstrIterator(), MI);
|
2011-12-06 23:12:01 +01:00
|
|
|
}
|
|
|
|
|
2012-12-18 00:55:38 +01:00
|
|
|
/// Remove an instruction from the instruction list and delete it.
|
2011-12-14 03:11:42 +01:00
|
|
|
///
|
2012-12-18 00:55:38 +01:00
|
|
|
/// If the instruction is part of a bundle, the other instructions in the
|
|
|
|
/// bundle will still be bundled after removing the single instruction.
|
|
|
|
instr_iterator erase(instr_iterator I);
|
|
|
|
|
|
|
|
/// Remove an instruction from the instruction list and delete it.
|
|
|
|
///
|
|
|
|
/// If the instruction is part of a bundle, the other instructions in the
|
|
|
|
/// bundle will still be bundled after removing the single instruction.
|
2011-12-14 03:11:42 +01:00
|
|
|
instr_iterator erase_instr(MachineInstr *I) {
|
2012-12-18 00:55:38 +01:00
|
|
|
return erase(instr_iterator(I));
|
2011-12-06 23:12:01 +01:00
|
|
|
}
|
2011-12-14 03:11:42 +01:00
|
|
|
|
2012-12-18 00:55:38 +01:00
|
|
|
/// Remove a range of instructions from the instruction list and delete them.
|
2011-12-06 23:12:01 +01:00
|
|
|
iterator erase(iterator I, iterator E) {
|
2016-02-22 22:30:15 +01:00
|
|
|
return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
|
2011-12-14 03:11:42 +01:00
|
|
|
}
|
2012-12-18 00:55:38 +01:00
|
|
|
|
|
|
|
/// Remove an instruction or bundle from the instruction list and delete it.
|
|
|
|
///
|
|
|
|
/// If I points to a bundle of instructions, they are all erased.
|
|
|
|
iterator erase(iterator I) {
|
2014-03-02 13:27:27 +01:00
|
|
|
return erase(I, std::next(I));
|
2012-12-18 00:55:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Remove an instruction from the instruction list and delete it.
|
|
|
|
///
|
|
|
|
/// If I is the head of a bundle of instructions, the whole bundle will be
|
|
|
|
/// erased.
|
2011-12-14 03:11:42 +01:00
|
|
|
iterator erase(MachineInstr *I) {
|
2012-12-18 00:55:38 +01:00
|
|
|
return erase(iterator(I));
|
2011-12-06 23:12:01 +01:00
|
|
|
}
|
|
|
|
|
2012-12-18 00:55:38 +01:00
|
|
|
/// Remove the unbundled instruction from the instruction list without
|
|
|
|
/// deleting it.
|
|
|
|
///
|
|
|
|
/// This function can not be used to remove bundled instructions, use
|
|
|
|
/// remove_instr to remove individual instructions from a bundle.
|
|
|
|
MachineInstr *remove(MachineInstr *I) {
|
|
|
|
assert(!I->isBundled() && "Cannot remove bundled instructions");
|
2015-10-09 18:54:49 +02:00
|
|
|
return Insts.remove(instr_iterator(I));
|
2012-12-18 00:55:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Remove the possibly bundled instruction from the instruction list
|
|
|
|
/// without deleting it.
|
|
|
|
///
|
|
|
|
/// If the instruction is part of a bundle, the other instructions in the
|
|
|
|
/// bundle will still be bundled after removing the single instruction.
|
|
|
|
MachineInstr *remove_instr(MachineInstr *I);
|
|
|
|
|
2011-12-14 03:11:42 +01:00
|
|
|
void clear() {
|
|
|
|
Insts.clear();
|
|
|
|
}
|
2005-04-21 22:39:54 +02:00
|
|
|
|
2012-12-18 21:59:41 +01:00
|
|
|
/// Take an instruction from MBB 'Other' at the position From, and insert it
|
|
|
|
/// into this MBB right before 'Where'.
|
|
|
|
///
|
|
|
|
/// If From points to a bundle of instructions, the whole bundle is moved.
|
|
|
|
void splice(iterator Where, MachineBasicBlock *Other, iterator From) {
|
|
|
|
// The range splice() doesn't allow noop moves, but this one does.
|
|
|
|
if (Where != From)
|
2014-03-02 13:27:27 +01:00
|
|
|
splice(Where, Other, From, std::next(From));
|
2009-01-15 23:01:38 +01:00
|
|
|
}
|
|
|
|
|
2012-12-18 21:59:41 +01:00
|
|
|
/// Take a block of instructions from MBB 'Other' in the range [From, To),
|
|
|
|
/// and insert them into this MBB right before 'Where'.
|
|
|
|
///
|
|
|
|
/// The instruction at 'Where' must not be included in the range of
|
|
|
|
/// instructions to move.
|
|
|
|
void splice(iterator Where, MachineBasicBlock *Other,
|
|
|
|
iterator From, iterator To) {
|
2016-02-22 22:30:15 +01:00
|
|
|
Insts.splice(Where.getInstrIterator(), Other->Insts,
|
|
|
|
From.getInstrIterator(), To.getInstrIterator());
|
2004-07-31 11:59:04 +02:00
|
|
|
}
|
2002-10-28 03:08:43 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// This method unlinks 'this' from the containing function, and returns it,
|
|
|
|
/// but does not delete it.
|
2008-07-08 01:14:23 +02:00
|
|
|
MachineBasicBlock *removeFromParent();
|
2012-01-31 20:47:32 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// This method unlinks 'this' from the containing function and deletes it.
|
2008-07-08 01:14:23 +02:00
|
|
|
void eraseFromParent();
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Given a machine basic block that branched to 'Old', change the code and
|
|
|
|
/// CFG so that it branches to 'New' instead.
|
2007-06-04 08:44:01 +02:00
|
|
|
void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New);
|
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// 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.
|
2007-06-19 00:43:58 +02:00
|
|
|
bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
|
|
|
|
MachineBasicBlock *DestB,
|
2015-09-29 21:46:09 +02:00
|
|
|
bool IsCond);
|
2007-06-19 00:43:58 +02:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE
|
2018-05-09 04:42:00 +02:00
|
|
|
/// and DBG_LABEL instructions. Return UnknownLoc if there is none.
|
2011-12-14 03:11:42 +01:00
|
|
|
DebugLoc findDebugLoc(instr_iterator MBBI);
|
2011-12-06 23:12:01 +01:00
|
|
|
DebugLoc findDebugLoc(iterator MBBI) {
|
2016-02-22 22:30:15 +01:00
|
|
|
return findDebugLoc(MBBI.getInstrIterator());
|
2011-12-06 23:12:01 +01:00
|
|
|
}
|
2010-01-20 22:36:02 +01:00
|
|
|
|
2018-03-15 23:06:51 +01:00
|
|
|
/// Find the previous valid DebugLoc preceding MBBI, skipping and DBG_VALUE
|
|
|
|
/// instructions. Return UnknownLoc if there is none.
|
|
|
|
DebugLoc findPrevDebugLoc(instr_iterator MBBI);
|
|
|
|
DebugLoc findPrevDebugLoc(iterator MBBI) {
|
|
|
|
return findPrevDebugLoc(MBBI.getInstrIterator());
|
|
|
|
}
|
|
|
|
|
Make MachineBasicBlock::updateTerminator to update DebugLoc as well
Summary:
Currently MachineBasicBlock::updateTerminator simply drops DebugLoc for newly created branch instructions, which may cause incorrect stepping and/or imprecise sample profile data. Below is an example:
```
1 extern int bar(int x);
2
3 int foo(int *begin, int *end) {
4 int *i;
5 int ret = 0;
6 for (
7 i = begin ;
8 i != end ;
9 i++)
10 {
11 ret += bar(*i);
12 }
13 return ret;
14 }
```
Below is a bitcode of 'foo' at the end of LLVM-IR level optimizations with -O3:
```
define i32 @foo(i32* readonly %begin, i32* readnone %end) !dbg !4 {
entry:
%cmp6 = icmp eq i32* %begin, %end, !dbg !9
br i1 %cmp6, label %for.end, label %for.body.preheader, !dbg !12
for.body.preheader: ; preds = %entry
br label %for.body, !dbg !13
for.body: ; preds = %for.body.preheader, %for.body
%ret.08 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
%i.07 = phi i32* [ %incdec.ptr, %for.body ], [ %begin, %for.body.preheader ]
%0 = load i32, i32* %i.07, align 4, !dbg !13, !tbaa !15
%call = tail call i32 @bar(i32 %0), !dbg !19
%add = add nsw i32 %call, %ret.08, !dbg !20
%incdec.ptr = getelementptr inbounds i32, i32* %i.07, i64 1, !dbg !21
%cmp = icmp eq i32* %incdec.ptr, %end, !dbg !9
br i1 %cmp, label %for.end.loopexit, label %for.body, !dbg !12, !llvm.loop !22
for.end.loopexit: ; preds = %for.body
br label %for.end, !dbg !24
for.end: ; preds = %for.end.loopexit, %entry
%ret.0.lcssa = phi i32 [ 0, %entry ], [ %add, %for.end.loopexit ]
ret i32 %ret.0.lcssa, !dbg !24
}
```
where
```
!12 = !DILocation(line: 6, column: 3, scope: !11)
```
. As you can see, the terminator of 'entry' block, which is a loop control branch, has a DebugLoc of line 6, column 3. Howerver, after the execution of 'MachineBlock::updateTerminator' function, which is triggered by MachineSinking pass, the DebugLoc info is dropped as below (see there's no debug-location for JNE_1):
```
bb.0.entry:
successors: %bb.4(0x30000000), %bb.1.for.body.preheader(0x50000000)
liveins: %rdi, %rsi
%6 = COPY %rsi
%5 = COPY %rdi
%8 = SUB64rr %5, %6, implicit-def %eflags, debug-location !9
JNE_1 %bb.1.for.body.preheader, implicit %eflags
```
This patch addresses this issue and make newly created branch instructions to keep debug-location info.
Reviewers: aprantl, MatzeB, craig.topper, qcolombet
Reviewed By: qcolombet
Subscribers: qcolombet, llvm-commits
Differential Revision: https://reviews.llvm.org/D29596
llvm-svn: 294976
2017-02-13 19:15:31 +01:00
|
|
|
/// Find and return the merged DebugLoc of the branch instructions of the
|
|
|
|
/// block. Return UnknownLoc if there is none.
|
|
|
|
DebugLoc findBranchDebugLoc();
|
|
|
|
|
2012-09-12 12:18:23 +02:00
|
|
|
/// Possible outcome of a register liveness query to computeRegisterLiveness()
|
|
|
|
enum LivenessQueryResult {
|
2015-12-11 20:42:09 +01:00
|
|
|
LQR_Live, ///< Register is known to be (at least partially) live.
|
|
|
|
LQR_Dead, ///< Register is known to be fully dead.
|
|
|
|
LQR_Unknown ///< Register liveness not decidable from local neighborhood.
|
2012-09-12 12:18:23 +02:00
|
|
|
};
|
|
|
|
|
2017-12-07 11:40:31 +01:00
|
|
|
/// Return whether (physical) register \p Reg has been defined and not
|
|
|
|
/// killed as of just before \p Before.
|
2014-07-02 08:45:26 +02:00
|
|
|
///
|
2015-05-27 07:12:39 +02:00
|
|
|
/// Search is localised to a neighborhood of \p Neighborhood instructions
|
|
|
|
/// before (searching for defs or kills) and \p Neighborhood instructions
|
|
|
|
/// after (searching just for defs) \p Before.
|
2012-09-12 12:18:23 +02:00
|
|
|
///
|
2015-05-27 07:12:39 +02:00
|
|
|
/// \p Reg must be a physical register.
|
2012-09-12 12:18:23 +02:00
|
|
|
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
|
2015-05-27 07:12:39 +02:00
|
|
|
unsigned Reg,
|
|
|
|
const_iterator Before,
|
2017-05-25 01:10:29 +02:00
|
|
|
unsigned Neighborhood = 10) const;
|
2012-09-12 12:18:23 +02:00
|
|
|
|
2004-02-13 05:40:15 +01:00
|
|
|
// Debugging methods.
|
|
|
|
void dump() const;
|
2018-01-18 18:59:06 +01:00
|
|
|
void print(raw_ostream &OS, const SlotIndexes * = nullptr,
|
2018-01-18 19:05:15 +01:00
|
|
|
bool IsStandalone = true) const;
|
2015-06-27 00:04:20 +02:00
|
|
|
void print(raw_ostream &OS, ModuleSlotTracker &MST,
|
2018-01-18 19:05:15 +01:00
|
|
|
const SlotIndexes * = nullptr, bool IsStandalone = true) const;
|
2004-02-13 05:40:15 +01:00
|
|
|
|
2014-01-09 03:29:41 +01:00
|
|
|
// Printing method used by LoopInfo.
|
2014-07-02 08:45:26 +02:00
|
|
|
void printAsOperand(raw_ostream &OS, bool PrintType = true) const;
|
2014-01-09 03:29:41 +01:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// MachineBasicBlocks are uniquely numbered at the function level, unless
|
|
|
|
/// they're not in a MachineFunction yet, in which case this will return -1.
|
2004-05-12 23:35:20 +02:00
|
|
|
int getNumber() const { return Number; }
|
2006-10-03 22:16:45 +02:00
|
|
|
void setNumber(int N) { Number = N; }
|
2004-05-12 23:35:20 +02:00
|
|
|
|
2015-08-05 22:30:11 +02:00
|
|
|
/// Return the MCSymbol for this basic block.
|
2010-03-13 22:04:28 +01:00
|
|
|
MCSymbol *getSymbol() const;
|
2011-06-16 22:22:37 +02:00
|
|
|
|
2017-11-02 23:26:51 +01:00
|
|
|
Optional<uint64_t> getIrrLoopHeaderWeight() const {
|
|
|
|
return IrrLoopHeaderWeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setIrrLoopHeaderWeight(uint64_t Weight) {
|
|
|
|
IrrLoopHeaderWeight = Weight;
|
|
|
|
}
|
|
|
|
|
2011-06-16 22:22:37 +02:00
|
|
|
private:
|
2015-11-04 22:37:58 +01:00
|
|
|
/// Return probability iterator corresponding to the I successor iterator.
|
|
|
|
probability_iterator getProbabilityIterator(succ_iterator I);
|
|
|
|
const_probability_iterator
|
|
|
|
getProbabilityIterator(const_succ_iterator I) const;
|
|
|
|
|
2011-06-16 22:22:37 +02:00
|
|
|
friend class MachineBranchProbabilityInfo;
|
2015-08-14 01:10:16 +02:00
|
|
|
friend class MIPrinter;
|
2011-06-16 22:22:37 +02:00
|
|
|
|
2015-11-04 22:37:58 +01:00
|
|
|
/// Return probability of the edge from this block to MBB. This method should
|
|
|
|
/// NOT be called directly, but by using getEdgeProbability method from
|
|
|
|
/// MachineBranchProbabilityInfo class.
|
|
|
|
BranchProbability getSuccProbability(const_succ_iterator Succ) const;
|
2011-06-16 22:22:37 +02:00
|
|
|
|
|
|
|
// Methods used to maintain doubly linked list of blocks...
|
2016-08-30 20:40:47 +02:00
|
|
|
friend struct ilist_callback_traits<MachineBasicBlock>;
|
2004-04-28 06:15:06 +02:00
|
|
|
|
|
|
|
// Machine-CFG mutators
|
|
|
|
|
2017-07-20 00:28:08 +02:00
|
|
|
/// Add Pred as a predecessor of this MachineBasicBlock. Don't do this
|
2015-09-29 21:46:09 +02:00
|
|
|
/// unless you know what you're doing, because it doesn't update Pred's
|
|
|
|
/// successors list. Use Pred->addSuccessor instead.
|
|
|
|
void addPredecessor(MachineBasicBlock *Pred);
|
2004-04-28 06:15:06 +02:00
|
|
|
|
2015-09-29 21:46:09 +02:00
|
|
|
/// Remove Pred as a predecessor of this MachineBasicBlock. Don't do this
|
|
|
|
/// unless you know what you're doing, because it doesn't update Pred's
|
|
|
|
/// successors list. Use Pred->removeSuccessor instead.
|
|
|
|
void removePredecessor(MachineBasicBlock *Pred);
|
2002-07-09 00:40:34 +02:00
|
|
|
};
|
|
|
|
|
2009-07-24 12:36:58 +02:00
|
|
|
raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB);
|
2004-05-01 23:05:34 +02:00
|
|
|
|
2017-12-04 18:18:51 +01:00
|
|
|
/// Prints a machine basic block reference.
|
|
|
|
///
|
|
|
|
/// The format is:
|
|
|
|
/// %bb.5 - a machine basic block with MBB.getNumber() == 5.
|
|
|
|
///
|
|
|
|
/// Usage: OS << printMBBReference(MBB) << '\n';
|
|
|
|
Printable printMBBReference(const MachineBasicBlock &MBB);
|
|
|
|
|
2011-03-04 01:15:36 +01:00
|
|
|
// This is useful when building IndexedMaps keyed on basic block pointers.
|
2017-09-14 20:33:25 +02:00
|
|
|
struct MBB2NumberFunctor {
|
|
|
|
using argument_type = const MachineBasicBlock *;
|
2011-03-04 01:15:36 +01:00
|
|
|
unsigned operator()(const MachineBasicBlock *MBB) const {
|
|
|
|
return MBB->getNumber();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2004-05-01 23:05:34 +02:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// GraphTraits specializations for machine basic block graphs (machine-CFGs)
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// Provide specializations of GraphTraits to be able to treat a
|
2015-08-06 14:49:40 +02:00
|
|
|
// MachineFunction as a graph of MachineBasicBlocks.
|
2004-05-01 23:05:34 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
template <> struct GraphTraits<MachineBasicBlock *> {
|
2017-05-25 01:10:29 +02:00
|
|
|
using NodeRef = MachineBasicBlock *;
|
|
|
|
using ChildIteratorType = MachineBasicBlock::succ_iterator;
|
2004-05-01 23:05:34 +02:00
|
|
|
|
2016-08-22 23:09:30 +02:00
|
|
|
static NodeRef getEntryNode(MachineBasicBlock *BB) { return BB; }
|
2016-08-31 18:48:13 +02:00
|
|
|
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
|
|
|
|
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
|
2004-05-01 23:05:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
template <> struct GraphTraits<const MachineBasicBlock *> {
|
2017-05-25 01:10:29 +02:00
|
|
|
using NodeRef = const MachineBasicBlock *;
|
|
|
|
using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
|
2004-05-01 23:05:34 +02:00
|
|
|
|
2016-08-22 23:09:30 +02:00
|
|
|
static NodeRef getEntryNode(const MachineBasicBlock *BB) { return BB; }
|
2016-08-31 18:48:13 +02:00
|
|
|
static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); }
|
|
|
|
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
|
2004-05-01 23:05:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Provide specializations of GraphTraits to be able to treat a
|
2015-08-06 14:49:40 +02:00
|
|
|
// MachineFunction as a graph of MachineBasicBlocks and to walk it
|
2004-05-01 23:05:34 +02:00
|
|
|
// in inverse order. Inverse order for a function is considered
|
|
|
|
// to be when traversing the predecessor edges of a MBB
|
|
|
|
// instead of the successor edges.
|
|
|
|
//
|
2017-05-25 01:10:29 +02:00
|
|
|
template <> struct GraphTraits<Inverse<MachineBasicBlock*>> {
|
|
|
|
using NodeRef = MachineBasicBlock *;
|
|
|
|
using ChildIteratorType = MachineBasicBlock::pred_iterator;
|
|
|
|
|
2016-08-22 23:09:30 +02:00
|
|
|
static NodeRef getEntryNode(Inverse<MachineBasicBlock *> G) {
|
2004-05-01 23:05:34 +02:00
|
|
|
return G.Graph;
|
|
|
|
}
|
2017-05-25 01:10:29 +02:00
|
|
|
|
2016-08-31 18:48:13 +02:00
|
|
|
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
|
|
|
|
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
|
2004-05-01 23:05:34 +02:00
|
|
|
};
|
|
|
|
|
2017-05-25 01:10:29 +02:00
|
|
|
template <> struct GraphTraits<Inverse<const MachineBasicBlock*>> {
|
|
|
|
using NodeRef = const MachineBasicBlock *;
|
|
|
|
using ChildIteratorType = MachineBasicBlock::const_pred_iterator;
|
|
|
|
|
2016-08-22 23:09:30 +02:00
|
|
|
static NodeRef getEntryNode(Inverse<const MachineBasicBlock *> G) {
|
2005-04-21 22:39:54 +02:00
|
|
|
return G.Graph;
|
2004-05-01 23:05:34 +02:00
|
|
|
}
|
2017-05-25 01:10:29 +02:00
|
|
|
|
2016-08-31 18:48:13 +02:00
|
|
|
static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); }
|
|
|
|
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
|
2004-05-01 23:05:34 +02:00
|
|
|
};
|
|
|
|
|
2013-08-15 01:50:11 +02:00
|
|
|
/// MachineInstrSpan provides an interface to get an iteration range
|
|
|
|
/// containing the instruction it was initialized with, along with all
|
|
|
|
/// those instructions inserted prior to or following that instruction
|
|
|
|
/// at some point after the MachineInstrSpan is constructed.
|
|
|
|
class MachineInstrSpan {
|
|
|
|
MachineBasicBlock &MBB;
|
|
|
|
MachineBasicBlock::iterator I, B, E;
|
2017-05-25 01:10:29 +02:00
|
|
|
|
2013-08-15 01:50:11 +02:00
|
|
|
public:
|
|
|
|
MachineInstrSpan(MachineBasicBlock::iterator I)
|
|
|
|
: MBB(*I->getParent()),
|
|
|
|
I(I),
|
2014-03-02 13:27:27 +01:00
|
|
|
B(I == MBB.begin() ? MBB.end() : std::prev(I)),
|
|
|
|
E(std::next(I)) {}
|
2013-08-15 01:50:11 +02:00
|
|
|
|
|
|
|
MachineBasicBlock::iterator begin() {
|
2014-03-02 13:27:27 +01:00
|
|
|
return B == MBB.end() ? MBB.begin() : std::next(B);
|
2013-08-15 01:50:11 +02:00
|
|
|
}
|
|
|
|
MachineBasicBlock::iterator end() { return E; }
|
|
|
|
bool empty() { return begin() == end(); }
|
|
|
|
|
|
|
|
MachineBasicBlock::iterator getInitial() { return I; }
|
|
|
|
};
|
|
|
|
|
2016-12-16 12:10:26 +01:00
|
|
|
/// Increment \p It until it points to a non-debug instruction or to \p End
|
|
|
|
/// and return the resulting iterator. This function should only be used
|
|
|
|
/// MachineBasicBlock::{iterator, const_iterator, instr_iterator,
|
|
|
|
/// const_instr_iterator} and the respective reverse iterators.
|
|
|
|
template<typename IterT>
|
|
|
|
inline IterT skipDebugInstructionsForward(IterT It, IterT End) {
|
2018-05-09 04:42:00 +02:00
|
|
|
while (It != End && It->isDebugInstr())
|
2016-12-16 12:10:26 +01:00
|
|
|
It++;
|
|
|
|
return It;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Decrement \p It until it points to a non-debug instruction or to \p Begin
|
|
|
|
/// and return the resulting iterator. This function should only be used
|
|
|
|
/// MachineBasicBlock::{iterator, const_iterator, instr_iterator,
|
|
|
|
/// const_instr_iterator} and the respective reverse iterators.
|
|
|
|
template<class IterT>
|
|
|
|
inline IterT skipDebugInstructionsBackward(IterT It, IterT Begin) {
|
2018-05-09 04:42:00 +02:00
|
|
|
while (It != Begin && It->isDebugInstr())
|
2016-12-16 12:10:26 +01:00
|
|
|
It--;
|
|
|
|
return It;
|
|
|
|
}
|
|
|
|
|
2017-05-25 01:10:29 +02:00
|
|
|
} // end namespace llvm
|
2002-07-09 00:40:34 +02:00
|
|
|
|
2017-05-25 01:10:29 +02:00
|
|
|
#endif // LLVM_CODEGEN_MACHINEBASICBLOCK_H
|