Skip to content

Commit 7a2c5c6

Browse files
authored
[SandboxIR][NFC] Move User into a separate file (#110157)
1 parent ac2a281 commit 7a2c5c6

File tree

7 files changed

+238
-193
lines changed

7 files changed

+238
-193
lines changed

llvm/include/llvm/SandboxIR/Context.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace llvm::sandboxir {
1818
class Module;
1919
class Value;
2020
class Argument;
21+
class Constant;
2122

2223
class Context {
2324
protected:
@@ -69,9 +70,8 @@ class Context {
6970
return getOrCreateValueInternal(LLVMV, 0);
7071
}
7172
/// Get or create a sandboxir::Constant from an existing LLVM IR \p LLVMC.
72-
Constant *getOrCreateConstant(llvm::Constant *LLVMC) {
73-
return cast<Constant>(getOrCreateValueInternal(LLVMC, 0));
74-
}
73+
Constant *getOrCreateConstant(llvm::Constant *LLVMC);
74+
7575
// Friends for getOrCreateConstant().
7676
#define DEF_CONST(ID, CLASS) friend class CLASS;
7777
#include "llvm/SandboxIR/SandboxIRValues.def"
@@ -158,9 +158,7 @@ class Context {
158158
friend FCmpInst; // For createFCmpInst()
159159

160160
public:
161-
Context(LLVMContext &LLVMCtx)
162-
: LLVMCtx(LLVMCtx), IRTracker(*this),
163-
LLVMIRBuilder(LLVMCtx, ConstantFolder()) {}
161+
Context(LLVMContext &LLVMCtx);
164162

165163
Tracker &getTracker() { return IRTracker; }
166164
/// Convenience function for `getTracker().save()`

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 1 addition & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
#include "llvm/SandboxIR/Tracker.h"
115115
#include "llvm/SandboxIR/Type.h"
116116
#include "llvm/SandboxIR/Use.h"
117+
#include "llvm/SandboxIR/User.h"
117118
#include "llvm/SandboxIR/Value.h"
118119
#include "llvm/Support/raw_ostream.h"
119120
#include <iterator>
@@ -188,42 +189,6 @@ class CmpInst;
188189
class ICmpInst;
189190
class FCmpInst;
190191

191-
/// Iterator for the `Use` edges of a User's operands.
192-
/// \Returns the operand `Use` when dereferenced.
193-
class OperandUseIterator {
194-
sandboxir::Use Use;
195-
/// Don't let the user create a non-empty OperandUseIterator.
196-
OperandUseIterator(const class Use &Use) : Use(Use) {}
197-
friend class User; // For constructor
198-
#define DEF_INSTR(ID, OPC, CLASS) friend class CLASS; // For constructor
199-
#include "llvm/SandboxIR/SandboxIRValues.def"
200-
201-
public:
202-
using difference_type = std::ptrdiff_t;
203-
using value_type = sandboxir::Use;
204-
using pointer = value_type *;
205-
using reference = value_type &;
206-
using iterator_category = std::input_iterator_tag;
207-
208-
OperandUseIterator() = default;
209-
value_type operator*() const;
210-
OperandUseIterator &operator++();
211-
OperandUseIterator operator++(int) {
212-
auto Copy = *this;
213-
this->operator++();
214-
return Copy;
215-
}
216-
bool operator==(const OperandUseIterator &Other) const {
217-
return Use == Other.Use;
218-
}
219-
bool operator!=(const OperandUseIterator &Other) const {
220-
return !(*this == Other);
221-
}
222-
OperandUseIterator operator+(unsigned Num) const;
223-
OperandUseIterator operator-(unsigned Num) const;
224-
int operator-(const OperandUseIterator &Other) const;
225-
};
226-
227192
/// Argument of a sandboxir::Function.
228193
class Argument : public sandboxir::Value {
229194
Argument(llvm::Argument *Arg, sandboxir::Context &Ctx)
@@ -243,97 +208,6 @@ class Argument : public sandboxir::Value {
243208
#endif
244209
};
245210

246-
/// A sandboxir::User has operands.
247-
class User : public Value {
248-
protected:
249-
User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
250-
251-
/// \Returns the Use edge that corresponds to \p OpIdx.
252-
/// Note: This is the default implementation that works for instructions that
253-
/// match the underlying LLVM instruction. All others should use a different
254-
/// implementation.
255-
Use getOperandUseDefault(unsigned OpIdx, bool Verify) const;
256-
/// \Returns the Use for the \p OpIdx'th operand. This is virtual to allow
257-
/// instructions to deviate from the LLVM IR operands, which is a requirement
258-
/// for sandboxir Instructions that consist of more than one LLVM Instruction.
259-
virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const = 0;
260-
friend class OperandUseIterator; // for getOperandUseInternal()
261-
262-
/// The default implementation works only for single-LLVMIR-instruction
263-
/// Users and only if they match exactly the LLVM instruction.
264-
unsigned getUseOperandNoDefault(const Use &Use) const {
265-
return Use.LLVMUse->getOperandNo();
266-
}
267-
/// \Returns the operand index of \p Use.
268-
virtual unsigned getUseOperandNo(const Use &Use) const = 0;
269-
friend unsigned Use::getOperandNo() const; // For getUseOperandNo()
270-
271-
void swapOperandsInternal(unsigned OpIdxA, unsigned OpIdxB) {
272-
assert(OpIdxA < getNumOperands() && "OpIdxA out of bounds!");
273-
assert(OpIdxB < getNumOperands() && "OpIdxB out of bounds!");
274-
auto UseA = getOperandUse(OpIdxA);
275-
auto UseB = getOperandUse(OpIdxB);
276-
UseA.swap(UseB);
277-
}
278-
279-
#ifndef NDEBUG
280-
void verifyUserOfLLVMUse(const llvm::Use &Use) const;
281-
#endif // NDEBUG
282-
283-
public:
284-
/// For isa/dyn_cast.
285-
static bool classof(const Value *From);
286-
using op_iterator = OperandUseIterator;
287-
using const_op_iterator = OperandUseIterator;
288-
using op_range = iterator_range<op_iterator>;
289-
using const_op_range = iterator_range<const_op_iterator>;
290-
291-
virtual op_iterator op_begin() {
292-
assert(isa<llvm::User>(Val) && "Expect User value!");
293-
return op_iterator(getOperandUseInternal(0, /*Verify=*/false));
294-
}
295-
virtual op_iterator op_end() {
296-
assert(isa<llvm::User>(Val) && "Expect User value!");
297-
return op_iterator(
298-
getOperandUseInternal(getNumOperands(), /*Verify=*/false));
299-
}
300-
virtual const_op_iterator op_begin() const {
301-
return const_cast<User *>(this)->op_begin();
302-
}
303-
virtual const_op_iterator op_end() const {
304-
return const_cast<User *>(this)->op_end();
305-
}
306-
307-
op_range operands() { return make_range<op_iterator>(op_begin(), op_end()); }
308-
const_op_range operands() const {
309-
return make_range<const_op_iterator>(op_begin(), op_end());
310-
}
311-
Value *getOperand(unsigned OpIdx) const { return getOperandUse(OpIdx).get(); }
312-
/// \Returns the operand edge for \p OpIdx. NOTE: This should also work for
313-
/// OpIdx == getNumOperands(), which is used for op_end().
314-
Use getOperandUse(unsigned OpIdx) const {
315-
return getOperandUseInternal(OpIdx, /*Verify=*/true);
316-
}
317-
virtual unsigned getNumOperands() const {
318-
return isa<llvm::User>(Val) ? cast<llvm::User>(Val)->getNumOperands() : 0;
319-
}
320-
321-
virtual void setOperand(unsigned OperandIdx, Value *Operand);
322-
/// Replaces any operands that match \p FromV with \p ToV. Returns whether any
323-
/// operands were replaced.
324-
bool replaceUsesOfWith(Value *FromV, Value *ToV);
325-
326-
#ifndef NDEBUG
327-
void verify() const override {
328-
assert(isa<llvm::User>(Val) && "Expected User!");
329-
}
330-
void dumpCommonHeader(raw_ostream &OS) const final;
331-
void dumpOS(raw_ostream &OS) const override {
332-
// TODO: Remove this tmp implementation once we get the Instruction classes.
333-
}
334-
#endif
335-
};
336-
337211
class Constant : public sandboxir::User {
338212
protected:
339213
Constant(llvm::Constant *C, sandboxir::Context &SBCtx)

llvm/include/llvm/SandboxIR/User.h

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//===- User.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+
#ifndef LLVM_SANDBOXIR_USER_H
10+
#define LLVM_SANDBOXIR_USER_H
11+
12+
#include "llvm/IR/User.h"
13+
#include "llvm/IR/Value.h"
14+
#include "llvm/SandboxIR/Use.h"
15+
#include "llvm/SandboxIR/Value.h"
16+
17+
namespace llvm::sandboxir {
18+
19+
class Context;
20+
21+
/// Iterator for the `Use` edges of a User's operands.
22+
/// \Returns the operand `Use` when dereferenced.
23+
class OperandUseIterator {
24+
sandboxir::Use Use;
25+
/// Don't let the user create a non-empty OperandUseIterator.
26+
OperandUseIterator(const class Use &Use) : Use(Use) {}
27+
friend class User; // For constructor
28+
#define DEF_INSTR(ID, OPC, CLASS) friend class CLASS; // For constructor
29+
#include "llvm/SandboxIR/SandboxIRValues.def"
30+
31+
public:
32+
using difference_type = std::ptrdiff_t;
33+
using value_type = sandboxir::Use;
34+
using pointer = value_type *;
35+
using reference = value_type &;
36+
using iterator_category = std::input_iterator_tag;
37+
38+
OperandUseIterator() = default;
39+
value_type operator*() const;
40+
OperandUseIterator &operator++();
41+
OperandUseIterator operator++(int) {
42+
auto Copy = *this;
43+
this->operator++();
44+
return Copy;
45+
}
46+
bool operator==(const OperandUseIterator &Other) const {
47+
return Use == Other.Use;
48+
}
49+
bool operator!=(const OperandUseIterator &Other) const {
50+
return !(*this == Other);
51+
}
52+
OperandUseIterator operator+(unsigned Num) const;
53+
OperandUseIterator operator-(unsigned Num) const;
54+
int operator-(const OperandUseIterator &Other) const;
55+
};
56+
57+
/// A sandboxir::User has operands.
58+
class User : public Value {
59+
protected:
60+
User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
61+
62+
/// \Returns the Use edge that corresponds to \p OpIdx.
63+
/// Note: This is the default implementation that works for instructions that
64+
/// match the underlying LLVM instruction. All others should use a different
65+
/// implementation.
66+
Use getOperandUseDefault(unsigned OpIdx, bool Verify) const;
67+
/// \Returns the Use for the \p OpIdx'th operand. This is virtual to allow
68+
/// instructions to deviate from the LLVM IR operands, which is a requirement
69+
/// for sandboxir Instructions that consist of more than one LLVM Instruction.
70+
virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const = 0;
71+
friend class OperandUseIterator; // for getOperandUseInternal()
72+
73+
/// The default implementation works only for single-LLVMIR-instruction
74+
/// Users and only if they match exactly the LLVM instruction.
75+
unsigned getUseOperandNoDefault(const Use &Use) const {
76+
return Use.LLVMUse->getOperandNo();
77+
}
78+
/// \Returns the operand index of \p Use.
79+
virtual unsigned getUseOperandNo(const Use &Use) const = 0;
80+
friend unsigned Use::getOperandNo() const; // For getUseOperandNo()
81+
82+
void swapOperandsInternal(unsigned OpIdxA, unsigned OpIdxB) {
83+
assert(OpIdxA < getNumOperands() && "OpIdxA out of bounds!");
84+
assert(OpIdxB < getNumOperands() && "OpIdxB out of bounds!");
85+
auto UseA = getOperandUse(OpIdxA);
86+
auto UseB = getOperandUse(OpIdxB);
87+
UseA.swap(UseB);
88+
}
89+
90+
#ifndef NDEBUG
91+
void verifyUserOfLLVMUse(const llvm::Use &Use) const;
92+
#endif // NDEBUG
93+
94+
public:
95+
/// For isa/dyn_cast.
96+
static bool classof(const Value *From);
97+
using op_iterator = OperandUseIterator;
98+
using const_op_iterator = OperandUseIterator;
99+
using op_range = iterator_range<op_iterator>;
100+
using const_op_range = iterator_range<const_op_iterator>;
101+
102+
virtual op_iterator op_begin() {
103+
assert(isa<llvm::User>(Val) && "Expect User value!");
104+
return op_iterator(getOperandUseInternal(0, /*Verify=*/false));
105+
}
106+
virtual op_iterator op_end() {
107+
assert(isa<llvm::User>(Val) && "Expect User value!");
108+
return op_iterator(
109+
getOperandUseInternal(getNumOperands(), /*Verify=*/false));
110+
}
111+
virtual const_op_iterator op_begin() const {
112+
return const_cast<User *>(this)->op_begin();
113+
}
114+
virtual const_op_iterator op_end() const {
115+
return const_cast<User *>(this)->op_end();
116+
}
117+
118+
op_range operands() { return make_range<op_iterator>(op_begin(), op_end()); }
119+
const_op_range operands() const {
120+
return make_range<const_op_iterator>(op_begin(), op_end());
121+
}
122+
Value *getOperand(unsigned OpIdx) const { return getOperandUse(OpIdx).get(); }
123+
/// \Returns the operand edge for \p OpIdx. NOTE: This should also work for
124+
/// OpIdx == getNumOperands(), which is used for op_end().
125+
Use getOperandUse(unsigned OpIdx) const {
126+
return getOperandUseInternal(OpIdx, /*Verify=*/true);
127+
}
128+
virtual unsigned getNumOperands() const {
129+
return isa<llvm::User>(Val) ? cast<llvm::User>(Val)->getNumOperands() : 0;
130+
}
131+
132+
virtual void setOperand(unsigned OperandIdx, Value *Operand);
133+
/// Replaces any operands that match \p FromV with \p ToV. Returns whether any
134+
/// operands were replaced.
135+
bool replaceUsesOfWith(Value *FromV, Value *ToV);
136+
137+
#ifndef NDEBUG
138+
void verify() const override {
139+
assert(isa<llvm::User>(Val) && "Expected User!");
140+
}
141+
void dumpCommonHeader(raw_ostream &OS) const final;
142+
void dumpOS(raw_ostream &OS) const override {
143+
// TODO: Remove this tmp implementation once we get the Instruction classes.
144+
}
145+
#endif
146+
};
147+
148+
} // namespace llvm::sandboxir
149+
150+
#endif // LLVM_SANDBOXIR_USER_H

llvm/lib/SandboxIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMSandboxIR
66
SandboxIR.cpp
77
Tracker.cpp
88
Type.cpp
9+
User.cpp
910
Value.cpp
1011

1112
ADDITIONAL_HEADER_DIRS

llvm/lib/SandboxIR/Context.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ Argument *Context::getOrCreateArgument(llvm::Argument *LLVMArg) {
409409
return cast<Argument>(It->second.get());
410410
}
411411

412+
Constant *Context::getOrCreateConstant(llvm::Constant *LLVMC) {
413+
return cast<Constant>(getOrCreateValueInternal(LLVMC, 0));
414+
}
415+
412416
BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
413417
assert(getValue(LLVMBB) == nullptr && "Already exists!");
414418
auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
@@ -662,6 +666,10 @@ Value *Context::getValue(llvm::Value *V) const {
662666
return nullptr;
663667
}
664668

669+
Context::Context(LLVMContext &LLVMCtx)
670+
: LLVMCtx(LLVMCtx), IRTracker(*this),
671+
LLVMIRBuilder(LLVMCtx, ConstantFolder()) {}
672+
665673
Module *Context::getModule(llvm::Module *LLVMM) const {
666674
auto It = LLVMModuleToModuleMap.find(LLVMM);
667675
if (It != LLVMModuleToModuleMap.end())

0 commit comments

Comments
 (0)