LLVM 22.0.0git
ControlFlowUtils.h
Go to the documentation of this file.
1//===- Transforms/Utils/ControlFlowUtils.h --------------------*- C++ -*---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Utilities to manipulate the CFG and restore SSA for the new control flow.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_TRANSFORMS_UTILS_CONTROLFLOWUTILS_H
14#define LLVM_TRANSFORMS_UTILS_CONTROLFLOWUTILS_H
15
17#include "llvm/ADT/StringRef.h"
18#include "llvm/IR/CycleInfo.h"
19
20namespace llvm {
21
22class BasicBlock;
23class CallBrInst;
24class LoopInfo;
25class DomTreeUpdater;
26
27/// Given a set of branch descriptors [BB, Succ0, Succ1], create a "hub" such
28/// that the control flow from each BB to a successor is now split into two
29/// edges, one from BB to the hub and another from the hub to the successor. The
30/// hub consists of a series of guard blocks, one for each outgoing block. Each
31/// guard block conditionally branches to the corresponding outgoing block, or
32/// the next guard block in the chain. These guard blocks are returned in the
33/// argument vector.
34///
35/// This also updates any PHINodes in the successor. For each such PHINode, the
36/// operands corresponding to incoming blocks are moved to a new PHINode in the
37/// hub, and the hub is made an operand of the original PHINode.
38///
39/// Note that for some block BB with a conditional branch, it is not necessary
40/// that both successors are rerouted. The client specifies this by setting
41/// either Succ0 or Succ1 to nullptr, in which case, the corresponding successor
42/// is not rerouted.
43///
44/// Input CFG:
45/// ----------
46///
47/// Def
48/// |
49/// v
50/// In1 In2
51/// | |
52/// | |
53/// v v
54/// Foo ---> Out1 Out2
55/// |
56/// v
57/// Use
58///
59///
60/// Create hub: Incoming = {In1, In2}, Outgoing = {Out1, Out2}
61/// ----------------------------------------------------------
62///
63/// Def
64/// |
65/// v
66/// In1 In2 Foo
67/// | Hub | |
68/// | + - - | - - + |
69/// | ' v ' V
70/// +------> Guard1 -----> Out1
71/// ' | '
72/// ' v '
73/// ' Guard2 -----> Out2
74/// ' ' |
75/// + - - - - - + |
76/// v
77/// Use
78///
79/// Limitations:
80/// -----------
81/// 1. This assumes that all terminators in the CFG are direct branches (the
82/// "br" instruction). The presence of any other control flow such as
83/// indirectbr, switch or callbr will cause an assert.
84///
85/// 2. The updates to the PHINodes are not sufficient to restore SSA
86/// form. Consider a definition Def, its use Use, incoming block In2 and
87/// outgoing block Out2, such that:
88/// a. In2 is reachable from D or contains D.
89/// b. U is reachable from Out2 or is contained in Out2.
90/// c. U is not a PHINode if U is contained in Out2.
91///
92/// Clearly, Def dominates Out2 since the program is valid SSA. But when the
93/// hub is introduced, there is a new path through the hub along which Use is
94/// reachable from entry without passing through Def, and SSA is no longer
95/// valid. To fix this, we need to look at all the blocks post-dominated by
96/// the hub on the one hand, and dominated by Out2 on the other. This is left
97/// for the caller to accomplish, since each specific use of this function
98/// may have additional information which simplifies this fixup. For example,
99/// see restoreSSA() in the UnifyLoopExits pass.
109
111 BasicBlock *Succ1 = nullptr) {
112 assert(BB);
113 assert(Succ0 || Succ1);
114 Branches.emplace_back(BB, Succ0, Succ1);
115 }
116
117 /// Return the unified loop exit block and a flag indicating if the CFG was
118 /// changed at all.
119 std::pair<BasicBlock *, bool>
121 const StringRef Prefix,
122 std::optional<unsigned> MaxControlFlowBooleans = std::nullopt);
123
125};
126
127} // end namespace llvm
128
129#endif // LLVM_TRANSFORMS_UTILS_CONTROLFLOWUTILS_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
arc branch finalize
This file declares the LLVM IR specialization of the GenericCycle templates.
This file defines the SmallVector class.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
This is an optimization pass for GlobalISel generic memory operations.
BranchDescriptor(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1)
Given a set of branch descriptors [BB, Succ0, Succ1], create a "hub" such that the control flow from ...
void addBranch(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1=nullptr)
SmallVector< BranchDescriptor > Branches