LLVM 19.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
19namespace llvm {
20
21static bool isExpandableUser(User *U) {
22 return isa<ConstantExpr>(U) || isa<ConstantAggregate>(U);
23}
24
26 Constant *C) {
28 if (auto *CE = dyn_cast<ConstantExpr>(C)) {
29 NewInsts.push_back(CE->getAsInstruction(InsertPt));
30 } else if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) {
31 Value *V = PoisonValue::get(C->getType());
32 for (auto [Idx, Op] : enumerate(C->operands())) {
33 V = InsertValueInst::Create(V, Op, Idx, "", InsertPt);
34 NewInsts.push_back(cast<Instruction>(V));
35 }
36 } else if (isa<ConstantVector>(C)) {
37 Type *IdxTy = Type::getInt32Ty(C->getContext());
38 Value *V = PoisonValue::get(C->getType());
39 for (auto [Idx, Op] : enumerate(C->operands())) {
40 V = InsertElementInst::Create(V, Op, ConstantInt::get(IdxTy, Idx), "",
41 InsertPt);
42 NewInsts.push_back(cast<Instruction>(V));
43 }
44 } else {
45 llvm_unreachable("Not an expandable user");
46 }
47 return NewInsts;
48}
49
51 // Find all expandable direct users of Consts.
53 for (Constant *C : Consts)
54 for (User *U : C->users())
55 if (isExpandableUser(U))
56 Stack.push_back(cast<Constant>(U));
57
58 // Include transitive users.
59 SetVector<Constant *> ExpandableUsers;
60 while (!Stack.empty()) {
61 Constant *C = Stack.pop_back_val();
62 if (!ExpandableUsers.insert(C))
63 continue;
64
65 for (auto *Nested : C->users())
66 if (isExpandableUser(Nested))
67 Stack.push_back(cast<Constant>(Nested));
68 }
69
70 // Find all instructions that use any of the expandable users
72 for (Constant *C : ExpandableUsers)
73 for (User *U : C->users())
74 if (auto *I = dyn_cast<Instruction>(U))
75 InstructionWorklist.insert(I);
76
77 // Replace those expandable operands with instructions
78 bool Changed = false;
79 while (!InstructionWorklist.empty()) {
80 Instruction *I = InstructionWorklist.pop_back_val();
81 DebugLoc Loc = I->getDebugLoc();
82 for (Use &U : I->operands()) {
83 auto *BI = I;
84 if (auto *Phi = dyn_cast<PHINode>(I)) {
85 BasicBlock *BB = Phi->getIncomingBlock(U);
87 assert(It != BB->end() && "Unexpected empty basic block");
88 BI = &*It;
89 }
90
91 if (auto *C = dyn_cast<Constant>(U.get())) {
92 if (ExpandableUsers.contains(C)) {
93 Changed = true;
94 auto NewInsts = expandUser(BI, C);
95 for (auto *NI : NewInsts)
96 NI->setDebugLoc(Loc);
97 InstructionWorklist.insert(NewInsts.begin(), NewInsts.end());
98 U.set(NewInsts.back());
99 }
100 }
101 }
102 }
103
104 for (Constant *C : Consts)
105 C->removeDeadConstantUsers();
106
107 return Changed;
108}
109
110} // namespace llvm
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
iterator end()
Definition: BasicBlock.h:442
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:389
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:164
This is an important base class in LLVM.
Definition: Constant.h:41
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, BasicBlock::iterator InsertBefore)
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr, BasicBlock::iterator InsertBefore)
InstructionWorklist - This is the worklist management logic for InstCombine and other simplification ...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1827
A vector that has set insertion semantics.
Definition: SetVector.h:57
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
Definition: SetVector.h:254
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getInt32Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
LLVM Value Representation.
Definition: Value.h:74
#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.
Definition: AddressRanges.h:18
bool convertUsersOfConstantsToInstructions(ArrayRef< Constant * > Consts)
Replace constant expressions users of the given constants with instructions.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
Definition: STLExtras.h:2386
static bool isExpandableUser(User *U)
static SmallVector< Instruction *, 4 > expandUser(Instruction *InsertPt, Constant *C)