LLVM 22.0.0git
ReplaceConstant.cpp
Go to the documentation of this file.
1//===- ReplaceConstant.cpp - Replace LLVM constant expression--------------===//
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// This file implements a utility function for replacing LLVM constant
10// expressions by instructions.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/SetVector.h"
16#include "llvm/IR/Constants.h"
18
19using namespace llvm;
20
21static bool isExpandableUser(User *U) {
23}
24
27 NewInsts.clear();
28 if (auto *CE = dyn_cast<ConstantExpr>(C)) {
29 Instruction *ConstInst = CE->getAsInstruction();
30 ConstInst->insertBefore(*InsertPt->getParent(), InsertPt);
31 NewInsts.push_back(ConstInst);
32 } else if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) {
33 Value *V = PoisonValue::get(C->getType());
34 for (auto [Idx, Op] : enumerate(C->operands())) {
35 V = InsertValueInst::Create(V, Op, Idx, "", InsertPt);
36 NewInsts.push_back(cast<Instruction>(V));
37 }
38 } else if (isa<ConstantVector>(C)) {
39 Type *IdxTy = Type::getInt32Ty(C->getContext());
40 Value *V = PoisonValue::get(C->getType());
41 for (auto [Idx, Op] : enumerate(C->operands())) {
42 V = InsertElementInst::Create(V, Op, ConstantInt::get(IdxTy, Idx), "",
43 InsertPt);
44 NewInsts.push_back(cast<Instruction>(V));
45 }
46 } else {
47 llvm_unreachable("Not an expandable user");
48 }
49}
50
52 Function *RestrictToFunc,
53 bool RemoveDeadConstants,
54 bool IncludeSelf) {
55 // Find all expandable direct users of Consts.
57 for (Constant *C : Consts) {
59 "should not be expanding trivial constant users");
60
61 if (IncludeSelf) {
62 assert(isExpandableUser(C) && "One of the constants is not expandable");
63 Stack.push_back(C);
64 } else {
65 for (User *U : C->users())
66 if (isExpandableUser(U))
67 Stack.push_back(cast<Constant>(U));
68 }
69 }
70
71 // Include transitive users.
72 SetVector<Constant *> ExpandableUsers;
73 while (!Stack.empty()) {
74 Constant *C = Stack.pop_back_val();
75 if (!ExpandableUsers.insert(C))
76 continue;
77
78 for (auto *Nested : C->users())
79 if (isExpandableUser(Nested))
80 Stack.push_back(cast<Constant>(Nested));
81 }
82
83 // Find all instructions that use any of the expandable users
85 for (Constant *C : ExpandableUsers)
86 for (User *U : C->users())
87 if (auto *I = dyn_cast<Instruction>(U))
88 if (!RestrictToFunc || I->getFunction() == RestrictToFunc)
89 InstructionWorklist.insert(I);
90
91 // Replace those expandable operands with instructions
92 bool Changed = false;
93 // We need to cache the instructions we've already expanded to avoid expanding
94 // the same constant multiple times in the same basic block, which is
95 // problematic when the same constant is used in a phi node multiple times.
97 ConstantToInstructionMap;
98 while (!InstructionWorklist.empty()) {
99 Instruction *I = InstructionWorklist.pop_back_val();
100 DebugLoc Loc = I->getDebugLoc();
101 for (Use &U : I->operands()) {
102 BasicBlock::iterator BI = I->getIterator();
103 if (auto *Phi = dyn_cast<PHINode>(I)) {
104 BasicBlock *BB = Phi->getIncomingBlock(U);
105 BI = BB->getFirstInsertionPt();
106 assert(BI != BB->end() && "Unexpected empty basic block");
107 }
108
109 if (auto *C = dyn_cast<Constant>(U.get())) {
110 if (ExpandableUsers.contains(C)) {
111 Changed = true;
113 ConstantToInstructionMap[std::make_pair(C, BI->getParent())];
114 // If the cached instruction is after the insertion point, we need to
115 // create a new one. We can't simply move the cached instruction
116 // because its operands (also expanded instructions) might not
117 // dominate the new position.
118 if (NewInsts.empty() || BI->comesBefore(NewInsts.front()))
119 expandUser(BI, C, NewInsts);
120 for (auto *NI : NewInsts)
121 NI->setDebugLoc(Loc);
122 InstructionWorklist.insert_range(NewInsts);
123 U.set(NewInsts.back());
124 }
125 }
126 }
127 }
128
129 if (RemoveDeadConstants)
130 for (Constant *C : Consts)
131 C->removeDeadConstantUsers();
132
133 return Changed;
134}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define I(x, y, z)
Definition MD5.cpp:57
static bool isExpandableUser(User *U)
static void expandUser(BasicBlock::iterator InsertPt, Constant *C, SmallVector< Instruction *, 4 > &NewInsts)
This file implements a set that has insertion order iteration characteristics.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:472
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
This is an important base class in LLVM.
Definition Constant.h:43
A debug info location.
Definition DebugLoc.h:124
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
InstructionWorklist - This is the worklist management logic for InstCombine and other simplification ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A vector that has set insertion semantics.
Definition SetVector.h:58
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:149
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
Definition SetVector.h:250
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:296
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2472
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI bool convertUsersOfConstantsToInstructions(ArrayRef< Constant * > Consts, Function *RestrictToFunc=nullptr, bool RemoveDeadConstants=true, bool IncludeSelf=false)
Replace constant expressions users of the given constants with instructions.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559