• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef LIBLLVMBACKEND_LOWERING_LLVM_IR_CONSTRUCTOR_H
17 #define LIBLLVMBACKEND_LOWERING_LLVM_IR_CONSTRUCTOR_H
18 
19 #include "optimizer/ir/graph.h"
20 #include "optimizer/ir/graph_visitor.h"
21 #include "optimizer/ir/inst.h"
22 
23 #include "debug_data_builder.h"
24 #include "llvm_ark_interface.h"
25 
26 #include <llvm/IR/Function.h>
27 #include <llvm/IR/IRBuilder.h>
28 
29 namespace ark::compiler {
30 
31 class LLVMIrConstructor : public GraphVisitor {
32     bool IsSafeCast(Inst *inst, unsigned int index);
33     bool TryEmitIntrinsic(Inst *inst, RuntimeInterface::IntrinsicId arkId);
34 
35 private:
36     // Specific intrinsic Emitters
37     bool EmitFastPath(Inst *inst, RuntimeInterface::EntrypointId eid, uint32_t numArgs);
38     bool EmitStringEquals(Inst *inst);
39     bool EmitStringBuilderBool(Inst *inst);
40     bool EmitStringBuilderChar(Inst *inst);
41     bool EmitStringBuilderString(Inst *inst);
42     bool EmitStringConcat2(Inst *inst);
43     bool EmitStringConcat3(Inst *inst);
44     bool EmitStringConcat4(Inst *inst);
45     bool EmitStringCompareTo(Inst *inst);
46     bool EmitIsInf(Inst *inst);
47     bool EmitMemmoveUnchecked(Inst *inst);
48     bool EmitUnreachable(Inst *inst);
49     bool EmitNothing(Inst *inst);
50     bool EmitSlowPathEntry(Inst *inst);
51     bool EmitExclusiveLoadWithAcquire(Inst *inst);
52     bool EmitExclusiveStoreWithRelease(Inst *inst);
53     bool EmitInterpreterReturn(Inst *inst);
54     bool EmitTailCall(Inst *inst);
55     bool EmitCompressEightUtf16ToUtf8CharsUsingSimd(Inst *inst);
56     bool EmitCompressSixteenUtf16ToUtf8CharsUsingSimd(Inst *inst);
57     bool EmitMemCharU8X16UsingSimd(Inst *inst);
58     bool EmitMemCharU8X32UsingSimd(Inst *inst);
59     bool EmitMemCharU16X8UsingSimd(Inst *inst);
60     bool EmitMemCharU16X16UsingSimd(Inst *inst);
61     bool EmitReverseBytes(Inst *inst);
62     bool EmitMemoryFenceFull(Inst *inst);
63     bool EmitMemoryFenceRelease(Inst *inst);
64     bool EmitMemoryFenceAcquire(Inst *inst);
65     bool EmitRoundToPInf(Inst *inst);
66     bool EmitFround(Inst *inst);
67     bool EmitJsCastDoubleToChar(Inst *inst);
68     bool EmitCtlz(Inst *inst);
69     bool EmitCttz(Inst *inst);
70     bool EmitSignbit(Inst *inst);
71     bool EmitIsInteger(Inst *inst);
72     bool EmitIsSafeInteger(Inst *inst);
73     bool EmitRawBitcastToInt(Inst *inst);
74     bool EmitRawBitcastToLong(Inst *inst);
75     bool EmitRawBitcastFromInt(Inst *inst);
76     bool EmitRawBitcastFromLong(Inst *inst);
77     bool EmitStringGetCharsTlab(Inst *inst);
78     bool EmitStringHashCode(Inst *inst);
79     bool EmitWriteTlabStatsSafe(Inst *inst);
80     bool EmitExpandU8U16(Inst *inst);
81     bool EmitReverseHalfWords(Inst *inst);
82     bool EmitAtomicByteOr(Inst *inst);
83 
84 public:
85     llvm::Value *GetMappedValue(Inst *inst, DataType::Type type);
86     llvm::Value *GetInputValue(Inst *inst, size_t index, bool skipCoerce = false);
87     llvm::Value *GetInputValueFromConstant(ConstantInst *constant, DataType::Type pandaType);
88     template <typename T>
89     llvm::FunctionType *GetFunctionTypeForCall(T *inst);
90 
GetGraph()91     Graph *GetGraph() const
92     {
93         return graph_;
94     }
95 
GetFunc()96     llvm::Function *GetFunc()
97     {
98         return func_;
99     }
100 
GetBuilder()101     llvm::IRBuilder<> *GetBuilder()
102     {
103         return &builder_;
104     }
105 
GetBlocksToVisit()106     const ArenaVector<BasicBlock *> &GetBlocksToVisit() const override
107     {
108         return graph_->GetBlocksRPO();
109     }
110 
111 private:
112     // Initializers. BuildIr calls them
113     void BuildBasicBlocks(Marker normal);
114     void BuildInstructions(Marker normal);
115     void FillPhiInputs(BasicBlock *block, Marker normal);
116 
117     // Creator functions for internal usage
118 
119     llvm::CallInst *CreateEntrypointCall(RuntimeInterface::EntrypointId eid, Inst *inst,
120                                          llvm::ArrayRef<llvm::Value *> args = llvm::None);
121     llvm::CallInst *CreateIntrinsicCall(Inst *inst);
122     llvm::CallInst *CreateIntrinsicCall(Inst *inst, RuntimeInterface::IntrinsicId entryId,
123                                         llvm::ArrayRef<llvm::Value *> arguments);
124     llvm::Value *CreateAllocaForArgs(llvm::Type *type, uint32_t arraySize);
125     llvm::CallInst *CreateFastPathCall(Inst *inst, RuntimeInterface::EntrypointId eid,
126                                        llvm::ArrayRef<llvm::Value *> args = llvm::None);
127 
128     llvm::Value *CreateIsInstanceEntrypointCall(Inst *inst);
129     llvm::Value *CreateIsInstanceObject(llvm::Value *klassObj);
130     llvm::Value *CreateIsInstanceOther(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
131     llvm::Value *CreateIsInstanceArray(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
132     llvm::Value *CreateIsInstanceArrayObject(Inst *inst, llvm::Value *klassObj);
133     llvm::Value *CreateIsInstanceInnerBlock(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
134 
135     void CreateCheckCastEntrypointCall(Inst *inst);
136     void CreateCheckCastObject(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
137     void CreateCheckCastOther(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
138     void CreateCheckCastArray(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
139     void CreateCheckCastArrayObject(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
140     void CreateCheckCastInner(Inst *inst, llvm::Value *klassObj, llvm::Value *klassId);
141 
142     void CreateInterpreterReturnRestoreRegs(RegMask &regMask, size_t offset, bool fp);
143     llvm::Value *CreateLoadClassById(Inst *inst, uint32_t typeId, bool init);
144     llvm::Value *CreateBinaryOp(Inst *inst, llvm::Instruction::BinaryOps opcode);
145     llvm::Value *CreateBinaryImmOp(Inst *inst, llvm::Instruction::BinaryOps opcode, uint64_t c);
146     llvm::Value *CreateShiftOp(Inst *inst, llvm::Instruction::BinaryOps opcode);
147     llvm::Value *CreateSignDivMod(Inst *inst, llvm::Instruction::BinaryOps opcode);
148     llvm::Value *CreateFloatComparison(CmpInst *cmpInst, llvm::Value *x, llvm::Value *y);
149     llvm::Value *CreateIntegerComparison(CmpInst *inst, llvm::Value *x, llvm::Value *y);
150     llvm::Value *CreateNewArrayWithRuntime(Inst *inst);
151     llvm::Value *CreateNewObjectWithRuntime(Inst *inst);
152     llvm::Value *CreateResolveVirtualCallBuiltin(Inst *inst, llvm::Value *thiz, uint32_t methodId);
153     llvm::Value *CreateLoadManagedClassFromClass(llvm::Value *klass);
CreateIsNan(llvm::Value * value)154     llvm::Value *CreateIsNan(llvm::Value *value)
155     {
156         return builder_.CreateFCmp(llvm::FCmpInst::Predicate::FCMP_UNE, value, value);
157     }
158 
159     llvm::Value *CreateIsInf(llvm::Value *input);
160     llvm::Value *CreateIsInteger(Inst *inst, llvm::Value *input);
161     llvm::Value *CreateCastToInt(Inst *inst);
162     llvm::Value *CreateLoadWithOrdering(Inst *inst, llvm::Value *value, llvm::AtomicOrdering ordering,
163                                         const llvm::Twine &name = "");
164     llvm::Value *CreateStoreWithOrdering(llvm::Value *value, llvm::Value *ptr, llvm::AtomicOrdering ordering);
165     llvm::Value *CreateZerosCount(Inst *inst, llvm::Intrinsic::ID llvmId);
166     llvm::Value *CreateRoundArm64(Inst *inst, bool is64);
167     llvm::Value *CreateNewStringFromCharsTlab(Inst *inst, llvm::Value *offset, llvm::Value *length, llvm::Value *array);
168     llvm::Value *CreateNewStringFromStringTlab(Inst *inst, llvm::Value *stringVal);
169     void CreateDeoptimizationBranch(Inst *inst, llvm::Value *deoptimize, RuntimeInterface::EntrypointId exception,
170                                     llvm::ArrayRef<llvm::Value *> arguments = llvm::None);
171     llvm::CallInst *CreateDeoptimizeCall(Inst *inst, llvm::ArrayRef<llvm::Value *> arguments,
172                                          RuntimeInterface::EntrypointId exception);
173     ArenaVector<llvm::OperandBundleDef> CreateSaveStateBundle(Inst *inst, bool noReturn = false);
174     void EncodeSaveStateInputs(ArenaVector<llvm::Value *> *vals, SaveStateInst *ss);
175     void EncodeInlineInfo(Inst *inst, llvm::Instruction *instruction);
176     void CreatePreWRB(Inst *inst, llvm::Value *mem);
177     void CreatePostWRB(Inst *inst, llvm::Value *mem, llvm::Value *offset, llvm::Value *value);
178     llvm::Value *CreateMemoryFence(memory_order::Order order);
179     llvm::Value *CreateCondition(ConditionCode cc, llvm::Value *x, llvm::Value *y);
180     void CreateIf(Inst *inst, llvm::Value *cond, bool likely, bool unlikely);
181     llvm::Value *CreateReturn(llvm::Value *value);
182     llvm::CallInst *CreateTailCallFastPath(Inst *inst);
183     llvm::CallInst *CreateTailCallInterpreter(Inst *inst);
184     template <uint32_t VECTOR_SIZE>
185     void CreateCompressUtf16ToUtf8CharsUsingSimd(Inst *inst);
186 
187     // Getters
188     llvm::FunctionType *GetEntryFunctionType();
189 
GetEntrypointSizeType()190     llvm::IntegerType *GetEntrypointSizeType()
191     {
192         return builder_.getIntNTy(func_->getParent()->getDataLayout().getPointerSizeInBits(0));
193     }
194 
195     llvm::Value *ToSizeT(llvm::Value *value);
196     llvm::Value *ToSSizeT(llvm::Value *value);
197 
198     ArenaVector<llvm::Value *> GetArgumentsForCall(llvm::Value *callee, CallInst *call, bool skipFirst = false);
199     ArenaVector<llvm::Value *> GetIntrinsicArguments(llvm::FunctionType *intrinsicFunctionType, IntrinsicInst *inst);
200     void SetIntrinsicParamAttrs(llvm::CallInst *call, IntrinsicInst *inst, llvm::ArrayRef<llvm::Value *> args);
201 
202     llvm::Value *GetThreadRegValue();
203     llvm::Value *GetRealFrameRegValue();
204 
GetMethodArgument()205     llvm::Argument *GetMethodArgument()
206     {
207         ASSERT(func_ != nullptr);
208         ASSERT(GetGraph()->SupportManagedCode());
209         auto offset = 0;
210         return func_->arg_begin() + offset;
211     }
212 
GetArgument(size_t index)213     llvm::Argument *GetArgument(size_t index)
214     {
215         ASSERT(func_ != nullptr);
216         auto offset = 0;
217         if (GetGraph()->SupportManagedCode()) {
218             offset++;
219         }
220         return func_->arg_begin() + offset + index;
221     }
222 
223     llvm::Function *GetOrCreateFunctionForCall(ark::compiler::CallInst *call, void *method);
224 
225     llvm::Type *GetType(DataType::Type pandaType);
226     llvm::Type *GetExactType(DataType::Type targetType);
227 
228     llvm::Instruction::CastOps GetCastOp(DataType::Type from, DataType::Type to);
229 
230     llvm::Value *CoerceValue(llvm::Value *value, DataType::Type sourceType, DataType::Type targetType);
231     llvm::Value *CoerceValue(llvm::Value *value, llvm::Type *targetType);
232 
233     void ValueMapAdd(Inst *inst, llvm::Value *value, bool setName = true);
234     void FillValueMapForUsers(ArenaUnorderedMap<DataType::Type, llvm::Value *> *map, Inst *inst, llvm::Value *value);
235 
236     void WrapArkCall(Inst *orig, llvm::CallInst *call);
237 
AddBlock(BasicBlock * pb,llvm::BasicBlock * lb)238     void AddBlock(BasicBlock *pb, llvm::BasicBlock *lb)
239     {
240         ASSERT(blockTailMap_.count(pb) == 0);
241         blockTailMap_.insert({pb, lb});
242         blockHeadMap_.insert({pb, lb});
243     }
244 
SetCurrentBasicBlock(llvm::BasicBlock * block)245     void SetCurrentBasicBlock(llvm::BasicBlock *block)
246     {
247         builder_.SetInsertPoint(block);
248     }
249 
GetCurrentBasicBlock()250     llvm::BasicBlock *GetCurrentBasicBlock()
251     {
252         return builder_.GetInsertBlock();
253     }
254 
ReplaceTailBlock(BasicBlock * pandaBlock,llvm::BasicBlock * llvmBlock)255     void ReplaceTailBlock(BasicBlock *pandaBlock, llvm::BasicBlock *llvmBlock)
256     {
257         auto it = blockTailMap_.find(pandaBlock);
258         ASSERT(it != blockTailMap_.end());
259         it->second = llvmBlock;
260     }
261 
GetHeadBlock(BasicBlock * block)262     llvm::BasicBlock *GetHeadBlock(BasicBlock *block)
263     {
264         ASSERT(blockHeadMap_.count(block) == 1);
265         auto result = blockHeadMap_.at(block);
266         ASSERT(result != nullptr);
267         return result;
268     }
269 
GetTailBlock(BasicBlock * block)270     llvm::BasicBlock *GetTailBlock(BasicBlock *block)
271     {
272         ASSERT(blockTailMap_.count(block) == 1);
273         auto result = blockTailMap_.at(block);
274         ASSERT(result != nullptr);
275         return result;
276     }
277 
278     void InitializeEntryBlock(bool noInline);
279 
280     void MarkAsAllocation(llvm::CallInst *call);
281 
282 protected:
283     // Instruction Visitors
284 
285     static void VisitConstant(GraphVisitor *v, Inst *inst);
286     static void VisitNullPtr(GraphVisitor *v, Inst *inst);
287     static void VisitLiveIn(GraphVisitor *v, Inst *inst);
288     static void VisitParameter(GraphVisitor *v, Inst *inst);
289     static void VisitReturnVoid(GraphVisitor *v, Inst *inst);
290     static void VisitReturn(GraphVisitor *v, Inst *inst);
291     static void VisitReturnInlined(GraphVisitor *v, Inst *inst);
292     static void VisitReturnI(GraphVisitor *v, Inst *inst);
293     static void VisitTry(GraphVisitor *v, Inst *inst);
294     static void VisitSaveState(GraphVisitor *v, Inst *inst);
295     static void VisitSaveStateDeoptimize(GraphVisitor *v, Inst *inst);
296     static void VisitSafePoint(GraphVisitor *v, Inst *inst);
297     static void VisitNOP(GraphVisitor *v, Inst *inst);
298     static void VisitLiveOut(GraphVisitor *v, Inst *inst);
299     static void VisitSubOverflowCheck(GraphVisitor *v, Inst *inst);
300     static void VisitDeoptimize(GraphVisitor *v, Inst *inst);
301     static void VisitDeoptimizeIf(GraphVisitor *v, Inst *inst);
302     static void VisitNegativeCheck(GraphVisitor *v, Inst *inst);
303     static void VisitZeroCheck(GraphVisitor *v, Inst *inst);
304     static void VisitNullCheck(GraphVisitor *v, Inst *inst);
305     static void VisitBoundsCheck(GraphVisitor *v, Inst *inst);
306     static void VisitRefTypeCheck(GraphVisitor *v, Inst *inst);
307     static void VisitLoadString(GraphVisitor *v, Inst *inst);
308     static void VisitLenArray(GraphVisitor *v, Inst *inst);
309     static void VisitLoadArray(GraphVisitor *v, Inst *inst);
310     static void VisitLoadCompressedStringChar(GraphVisitor *v, Inst *inst);
311     static void VisitStoreArray(GraphVisitor *v, Inst *inst);
312     static void VisitLoad(GraphVisitor *v, Inst *inst);
313     static void VisitLoadNative(GraphVisitor *v, Inst *inst);
314     static void VisitStore(GraphVisitor *v, Inst *inst);
315     static void VisitStoreNative(GraphVisitor *v, Inst *inst);
316     static void VisitLoadI(GraphVisitor *v, Inst *inst);
317     static void VisitStoreI(GraphVisitor *v, Inst *inst);
318     static void VisitLoadObject(GraphVisitor *v, Inst *inst);
319     static void VisitStoreObject(GraphVisitor *v, Inst *inst);
320     static void VisitResolveObjectField(GraphVisitor *v, Inst *inst);
321     static void VisitLoadResolvedObjectField(GraphVisitor *v, Inst *inst);
322     static void VisitStoreResolvedObjectField(GraphVisitor *v, Inst *inst);
323     static void VisitResolveObjectFieldStatic(GraphVisitor *v, Inst *inst);
324     static void VisitLoadResolvedObjectFieldStatic(GraphVisitor *v, Inst *inst);
325     static void VisitStoreResolvedObjectFieldStatic(GraphVisitor *v, Inst *inst);
326     static void VisitBitcast(GraphVisitor *v, Inst *inst);
327     static void VisitCast(GraphVisitor *v, Inst *inst);
328     static void VisitAnd(GraphVisitor *v, Inst *inst);
329     static void VisitAndI(GraphVisitor *v, Inst *inst);
330     static void VisitOr(GraphVisitor *v, Inst *inst);
331     static void VisitOrI(GraphVisitor *v, Inst *inst);
332     static void VisitXor(GraphVisitor *v, Inst *inst);
333     static void VisitXorI(GraphVisitor *v, Inst *inst);
334     static void VisitShl(GraphVisitor *v, Inst *inst);
335     static void VisitShlI(GraphVisitor *v, Inst *inst);
336     static void VisitShr(GraphVisitor *v, Inst *inst);
337     static void VisitShrI(GraphVisitor *v, Inst *inst);
338     static void VisitAShr(GraphVisitor *v, Inst *inst);
339     static void VisitAShrI(GraphVisitor *v, Inst *inst);
340     static void VisitAdd(GraphVisitor *v, Inst *inst);
341     static void VisitAddI(GraphVisitor *v, Inst *inst);
342     static void VisitSub(GraphVisitor *v, Inst *inst);
343     static void VisitSubI(GraphVisitor *v, Inst *inst);
344     static void VisitMul(GraphVisitor *v, Inst *inst);
345     static void VisitMulI(GraphVisitor *v, Inst *inst);
346     static void VisitDiv(GraphVisitor *v, Inst *inst);
347     static void VisitMod(GraphVisitor *v, Inst *inst);
348     static void VisitMin(GraphVisitor *v, Inst *inst);
349     static void VisitMax(GraphVisitor *v, Inst *inst);
350     static void VisitCompare(GraphVisitor *v, Inst *inst);
351     static void VisitCmp(GraphVisitor *v, Inst *inst);
352     static void VisitNeg(GraphVisitor *v, Inst *inst);
353     static void VisitNot(GraphVisitor *v, Inst *inst);
354     static void VisitIfImm(GraphVisitor *v, Inst *inst);
355     static void VisitIf(GraphVisitor *v, Inst *inst);
356     static void VisitCallIndirect(GraphVisitor *v, Inst *inst);
357     static void VisitCall(GraphVisitor *v, Inst *inst);
358     static void VisitPhi(GraphVisitor *v, Inst *inst);
359     static void VisitMultiArray(GraphVisitor *v, Inst *inst);
360     static void VisitInitEmptyString(GraphVisitor *v, Inst *inst);
361     static void VisitInitString(GraphVisitor *v, Inst *inst);
362     static void VisitNewArray(GraphVisitor *v, Inst *inst);
363     static void VisitNewObject(GraphVisitor *v, Inst *inst);
364     static void VisitCallStatic(GraphVisitor *v, Inst *inst);
365     static void VisitResolveStatic(GraphVisitor *v, Inst *inst);
366     static void VisitCallResolvedStatic(GraphVisitor *v, Inst *inst);
367     static void VisitCallVirtual(GraphVisitor *v, Inst *inst);
368     static void VisitResolveVirtual(GraphVisitor *v, Inst *inst);
369     static void VisitCallResolvedVirtual(GraphVisitor *v, Inst *inst);
370     static void VisitAbs(GraphVisitor *v, Inst *inst);
371     static void VisitIntrinsic(GraphVisitor *v, Inst *inst);
372     static void VisitMonitor(GraphVisitor *v, Inst *inst);
373     static void VisitSqrt(GraphVisitor *v, Inst *inst);
374     static void VisitInitClass(GraphVisitor *v, Inst *inst);
375     static void VisitLoadClass(GraphVisitor *v, Inst *inst);
376     static void VisitLoadAndInitClass(GraphVisitor *v, Inst *inst);
377     static void VisitUnresolvedLoadAndInitClass(GraphVisitor *v, Inst *inst);
378     static void VisitLoadStatic(GraphVisitor *v, Inst *inst);
379     static void VisitStoreStatic(GraphVisitor *v, Inst *inst);
380     static void VisitUnresolvedStoreStatic(GraphVisitor *v, Inst *inst);
381     static void VisitLoadConstArray(GraphVisitor *v, Inst *inst);
382     static void VisitFillConstArray(GraphVisitor *v, Inst *inst);
383     static void VisitIsInstance(GraphVisitor *v, Inst *inst);
384     static void VisitCheckCast(GraphVisitor *v, Inst *inst);
385     static void VisitLoadType(GraphVisitor *v, Inst *inst);
386     static void VisitUnresolvedLoadType(GraphVisitor *v, Inst *inst);
387     static void VisitGetInstanceClass(GraphVisitor *v, Inst *inst);
388     static void VisitThrow(GraphVisitor *v, Inst *inst);
389     static void VisitCatchPhi(GraphVisitor *v, Inst *inst);
390     static void VisitLoadRuntimeClass(GraphVisitor *v, Inst *inst);
391     static void VisitLoadUniqueObject(GraphVisitor *v, Inst *inst);
392     static void VisitLoadImmediate(GraphVisitor *v, Inst *inst);
393 
394     void VisitDefault(Inst *inst) override;
395 
396 public:
397     explicit LLVMIrConstructor(Graph *graph, llvm::Module *module, llvm::LLVMContext *context,
398                                llvmbackend::LLVMArkInterface *arkInterface,
399                                const std::unique_ptr<llvmbackend::DebugDataBuilder> &debugData);
400 
401     bool BuildIr(bool preventInlining);
402 
403     static void InsertArkFrameInfo(llvm::Module *module, Arch arch);
404     static void ProvideSafepointPoll(llvm::Module *module, llvmbackend::LLVMArkInterface *arkInterface, Arch arch);
405 
406     static std::string CheckGraph(Graph *graph);
407     static bool CanCompile(Inst *inst);
408 
409 #ifndef NDEBUG
410     void BreakIrIfNecessary();
411 #endif
412 
413 #include "llvm_ir_constructor_gen.h.inl"
414 
415 #include "optimizer/ir/visitor.inc"
416 
417 private:
418     Graph *graph_ {nullptr};
419     llvm::Function *func_;
420     llvm::IRBuilder<> builder_;
421     ArenaDoubleUnorderedMap<Inst *, DataType::Type, llvm::Value *> inputMap_;
422     ArenaUnorderedMap<BasicBlock *, llvm::BasicBlock *> blockTailMap_;
423     ArenaUnorderedMap<BasicBlock *, llvm::BasicBlock *> blockHeadMap_;
424     llvmbackend::LLVMArkInterface *arkInterface_;
425     const std::unique_ptr<llvmbackend::DebugDataBuilder> &debugData_;
426     ArenaVector<uint8_t> cc_;
427     ArenaVector<llvm::Value *> ccValues_;
428 };
429 
430 }  // namespace ark::compiler
431 
432 #endif  // LIBLLVMBACKEND_LOWERING_LLVM_IR_CONSTRUCTOR_H
433