Jlm
IpGraphToLlvmConverter.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2025 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #ifndef JLM_LLVM_BACKEND_IPGRAPHTOLLVMCONVERTER_HPP
7 #define JLM_LLVM_BACKEND_IPGRAPHTOLLVMCONVERTER_HPP
8 
10 #include <jlm/llvm/ir/tac.hpp>
11 
12 #include <llvm/IR/Attributes.h>
13 #include <llvm/IR/InstrTypes.h>
14 #include <llvm/IR/IRBuilder.h>
15 
16 #include <memory>
17 
18 namespace llvm
19 {
20 class Instruction;
21 class LLVMContext;
22 class Module;
23 class Value;
24 }
25 
26 namespace jlm::rvsdg
27 {
28 class SimpleOperation;
29 }
30 
31 namespace jlm::llvm
32 {
33 class FunctionToPointerOperation;
34 
35 class ControlFlowGraph;
36 class DataNode;
37 class ConstantFP;
38 class PoisonValueOperation;
39 class CallOperation;
40 class LoadNonVolatileOperation;
41 class LoadVolatileOperation;
42 class StoreVolatileOperation;
43 class ConstantDataArray;
44 class ConstantArrayOperation;
45 class ConstantAggregateZeroOperation;
46 class ConstantStruct;
47 class ConstantPointerNullOperation;
48 class ShuffleVectorOperation;
49 class VectorSelectOperation;
50 class MallocOperation;
51 class FreeOperation;
52 class MemCpyNonVolatileOperation;
53 class MemCpyVolatileOperation;
54 class MemoryStateMergeOperation;
55 class MemoryStateSplitOperation;
56 class LambdaEntryMemoryStateSplitOperation;
57 class CallEntryMemoryStateMergeOperation;
58 class CallExitMemoryStateSplitOperation;
59 class ControlFlowGraphNode;
60 class ExtractValueOperation;
61 class FunctionNode;
62 class InterProceduralGraphModule;
63 class LambdaExitMemoryStateMergeOperation;
64 class PointerToFunctionOperation;
65 class ThreeAddressCode;
66 class Variable;
67 
69 {
70  class Context;
71 
72 public:
74 
76 
78 
80 
82  operator=(const IpGraphToLlvmConverter &) = delete;
83 
85  operator=(IpGraphToLlvmConverter &&) = delete;
86 
87  // FIXME: InterProceduralGraphModule should be const, but we still need to create variables to
88  // translate expressions.
89  std::unique_ptr<::llvm::Module>
90  ConvertModule(InterProceduralGraphModule & ipGraphModule, ::llvm::LLVMContext & llvmContext);
91 
92  static ::llvm::Attribute::AttrKind
93  ConvertAttributeKind(const Attribute::kind & kind);
94 
95  static std::unique_ptr<::llvm::Module>
96  CreateAndConvertModule(InterProceduralGraphModule & ipGraphModule, ::llvm::LLVMContext & ctx);
97 
98 private:
99  void
100  convert_ipgraph();
101 
102  const ::llvm::GlobalValue::LinkageTypes &
103  convert_linkage(const llvm::Linkage & linkage);
104 
105  void
106  convert_data_node(const DataNode & node);
107 
108  void
109  convert_function(const FunctionNode & node);
110 
111  void
112  convert_cfg(ControlFlowGraph & cfg, ::llvm::Function & f);
113 
114  std::vector<ControlFlowGraphNode *>
115  ConvertBasicBlocks(const ControlFlowGraph & controlFlowGraph, ::llvm::Function & function);
116 
117  ::llvm::AttributeList
118  convert_attributes(const FunctionNode & f);
119 
120  ::llvm::AttributeSet
121  convert_attributes(const AttributeSet & attributeSet);
122 
123  ::llvm::Attribute
124  ConvertStringAttribute(const llvm::StringAttribute & attribute);
125 
126  ::llvm::Attribute
127  ConvertTypeAttribute(const llvm::TypeAttribute & attribute);
128 
129  ::llvm::Attribute
130  ConvertIntAttribute(const llvm::IntAttribute & attribute);
131 
132  ::llvm::Attribute
133  ConvertEnumAttribute(const llvm::EnumAttribute & attribute);
134 
135  void
137 
138  void
139  create_switch(const ControlFlowGraphNode * node);
140 
141  void
143 
144  void
146 
147  void
148  create_return(const ControlFlowGraphNode * node);
149 
150  void
151  convert_tacs(const tacsvector_t & tacs);
152 
153  void
155 
156  ::llvm::Value *
158  const rvsdg::SimpleOperation & op,
159  const std::vector<const Variable *> & arguments,
160  ::llvm::IRBuilder<> & builder);
161 
162  template<class OP>
163  ::llvm::Value *
165  const rvsdg::SimpleOperation & op,
166  const std::vector<const Variable *> & operands,
167  ::llvm::IRBuilder<> & builder);
168 
169  ::llvm::Value *
170  convert(
172  const std::vector<const Variable *> & operands,
173  ::llvm::IRBuilder<> &);
174 
175  ::llvm::Value *
176  convert(
178  const std::vector<const Variable *> & operands,
179  ::llvm::IRBuilder<> &);
180 
181  ::llvm::Value *
182  convert(
184  const std::vector<const Variable *> &,
185  ::llvm::IRBuilder<> &);
186 
187  ::llvm::Value *
188  convert(
190  const std::vector<const Variable *> &,
191  ::llvm::IRBuilder<> &);
192 
193  ::llvm::Value *
194  convert(
196  const std::vector<const Variable *> &,
197  ::llvm::IRBuilder<> &);
198 
199  ::llvm::Value *
200  convert(
202  const std::vector<const Variable *> &,
203  ::llvm::IRBuilder<> &);
204 
205  ::llvm::Value *
206  convert(
208  const std::vector<const Variable *> &,
209  ::llvm::IRBuilder<> &);
210 
211  ::llvm::Value *
212  convert(
214  const std::vector<const Variable *> &,
215  ::llvm::IRBuilder<> &);
216 
217  ::llvm::Value *
218  convert(
219  const MemCpyVolatileOperation &,
220  const std::vector<const Variable *> & operands,
221  ::llvm::IRBuilder<> & builder);
222 
223  ::llvm::Value *
224  convert(
226  const std::vector<const Variable *> & operands,
227  ::llvm::IRBuilder<> & builder);
228 
229  ::llvm::Value *
230  convert(
231  const FreeOperation & op,
232  const std::vector<const Variable *> & args,
233  ::llvm::IRBuilder<> & builder);
234 
235  ::llvm::Value *
236  convert(
237  const MallocOperation & op,
238  const std::vector<const Variable *> & args,
239  ::llvm::IRBuilder<> & builder);
240 
241  ::llvm::Value *
242  convert(
243  const ExtractValueOperation & op,
244  const std::vector<const Variable *> & operands,
245  ::llvm::IRBuilder<> & builder);
246 
247  template<::llvm::Instruction::CastOps OPCODE>
248  ::llvm::Value *
250  const rvsdg::SimpleOperation & op,
251  const std::vector<const Variable *> & operands,
252  ::llvm::IRBuilder<> & builder);
253 
254  ::llvm::Value *
255  convert(
256  const VectorSelectOperation &,
257  const std::vector<const Variable *> & operands,
258  ::llvm::IRBuilder<> & builder);
259 
260  ::llvm::Value *
262  const rvsdg::SimpleOperation & op,
263  const std::vector<const Variable *> & operands,
264  ::llvm::IRBuilder<> & builder);
265 
266  ::llvm::Value *
268  const rvsdg::SimpleOperation & op,
269  const std::vector<const Variable *> & operands,
270  ::llvm::IRBuilder<> & builder);
271 
272  ::llvm::Value *
274  const rvsdg::SimpleOperation & op,
275  const std::vector<const Variable *> & operands,
276  ::llvm::IRBuilder<> & builder);
277 
278  ::llvm::Value *
279  convert(
280  const ShuffleVectorOperation & op,
281  const std::vector<const Variable *> & operands,
282  ::llvm::IRBuilder<> & builder);
283 
284  ::llvm::Value *
286  const rvsdg::SimpleOperation & op,
287  const std::vector<const Variable *> & args,
288  ::llvm::IRBuilder<> & builder);
289 
290  ::llvm::Value *
292  const rvsdg::SimpleOperation & op,
293  const std::vector<const Variable *> & operands,
294  ::llvm::IRBuilder<> & builder);
295 
296  ::llvm::Value *
298  const rvsdg::SimpleOperation & op,
299  const std::vector<const Variable *> & operands,
300  ::llvm::IRBuilder<> &);
301 
302  ::llvm::Value *
304  const rvsdg::SimpleOperation & op,
305  const std::vector<const Variable *> & args,
306  ::llvm::IRBuilder<> &);
307 
308  ::llvm::Value *
310  const rvsdg::SimpleOperation & op,
311  const std::vector<const Variable *> & operands,
312  ::llvm::IRBuilder<> & builder);
313 
314  ::llvm::Value *
315  convert(
316  const ConstantPointerNullOperation & operation,
317  const std::vector<const Variable *> &,
318  ::llvm::IRBuilder<> &);
319 
320  ::llvm::Value *
321  convert(
322  const ConstantStruct & op,
323  const std::vector<const Variable *> & args,
324  ::llvm::IRBuilder<> &);
325 
326  ::llvm::Value *
328  const rvsdg::SimpleOperation & op,
329  const std::vector<const Variable *> &,
330  ::llvm::IRBuilder<> &);
331 
332  ::llvm::Value *
334  const rvsdg::SimpleOperation & op,
335  const std::vector<const Variable *> & args,
336  ::llvm::IRBuilder<> & builder);
337 
338  ::llvm::Value *
340  const rvsdg::SimpleOperation & op,
341  const std::vector<const Variable *> & args,
342  ::llvm::IRBuilder<> & builder);
343 
344  ::llvm::Value *
346  const rvsdg::SimpleOperation & op,
347  const std::vector<const Variable *> & args,
348  ::llvm::IRBuilder<> & builder);
349 
350  ::llvm::Value *
352  const rvsdg::SimpleOperation & op,
353  const std::vector<const Variable *> & args,
354  ::llvm::IRBuilder<> & builder);
355 
356  ::llvm::Value *
357  convert(
359  const std::vector<const Variable *> &,
360  ::llvm::IRBuilder<> &);
361 
362  ::llvm::Value *
363  convert(
364  const ConstantArrayOperation & op,
365  const std::vector<const Variable *> & operands,
366  ::llvm::IRBuilder<> &);
367 
368  ::llvm::Value *
369  convert(
370  const ConstantDataArray & op,
371  const std::vector<const Variable *> & operands,
372  ::llvm::IRBuilder<> & builder);
373 
374  template<typename T>
375  std::vector<T>
376  get_fpdata(const std::vector<const Variable *> & args);
377 
378  template<typename T>
379  std::vector<T>
380  get_bitdata(const std::vector<const Variable *> & args);
381 
382  ::llvm::Value *
384  const rvsdg::SimpleOperation & op,
385  const std::vector<const Variable *> & args,
386  ::llvm::IRBuilder<> & builder);
387 
388  ::llvm::Value *
390  const rvsdg::SimpleOperation & op,
391  const std::vector<const Variable *> & args,
392  ::llvm::IRBuilder<> & builder);
393 
394  ::llvm::Value *
395  convert(
396  const StoreVolatileOperation & operation,
397  const std::vector<const Variable *> & operands,
398  ::llvm::IRBuilder<> & builder);
399 
400  ::llvm::Value *
402  const rvsdg::SimpleOperation & operation,
403  const std::vector<const Variable *> & operands,
404  ::llvm::IRBuilder<> & builder);
405 
406  void
408  const Variable * address,
409  const Variable * value,
410  bool isVolatile,
411  size_t alignment,
412  ::llvm::IRBuilder<> & builder);
413 
414  ::llvm::Value *
415  convert(
416  const LoadVolatileOperation & operation,
417  const std::vector<const Variable *> & operands,
418  ::llvm::IRBuilder<> & builder);
419 
420  ::llvm::Value *
421  convert(
422  const LoadNonVolatileOperation & operation,
423  const std::vector<const Variable *> & operands,
424  ::llvm::IRBuilder<> & builder);
425 
426  ::llvm::Value *
428  const rvsdg::Type & loadedType,
429  const Variable * address,
430  bool isVolatile,
431  size_t alignment,
432  ::llvm::IRBuilder<> & builder);
433 
434  ::llvm::Value *
435  convert_phi(
436  const rvsdg::SimpleOperation & op,
437  const std::vector<const Variable *> &,
438  ::llvm::IRBuilder<> & builder);
439 
440  ::llvm::Value *
442  const rvsdg::SimpleOperation & op,
443  const std::vector<const Variable *> &,
444  ::llvm::IRBuilder<> &);
445 
446  ::llvm::Value *
448  const rvsdg::SimpleOperation & op,
449  const std::vector<const Variable *> & args,
450  ::llvm::IRBuilder<> & builder);
451 
452  ::llvm::Value *
453  convert(
454  const CallOperation & op,
455  const std::vector<const Variable *> & args,
456  ::llvm::IRBuilder<> & builder);
457 
458  ::llvm::Value *
459  convert(
460  const PoisonValueOperation & operation,
461  const std::vector<const Variable *> &,
462  ::llvm::IRBuilder<> &);
463 
464  ::llvm::Value *
466  const rvsdg::SimpleOperation & op,
467  const std::vector<const Variable *> &,
468  ::llvm::IRBuilder<> &);
469 
470  ::llvm::Value *
471  convert(
472  const ConstantFP & op,
473  const std::vector<const Variable *> &,
474  ::llvm::IRBuilder<> & builder);
475 
476  ::llvm::Value *
478  const rvsdg::SimpleOperation & op,
479  const std::vector<const Variable *> &,
480  ::llvm::IRBuilder<> & builder);
481 
482  ::llvm::Value *
484  const rvsdg::SimpleOperation & op,
485  const std::vector<const Variable *> &,
486  ::llvm::IRBuilder<> & builder);
487 
488  ::llvm::Value *
490  const ::llvm::CmpInst::Predicate predicate,
491  const std::vector<const Variable *> & args,
492  ::llvm::IRBuilder<> & builder);
493 
494  ::llvm::Value *
496  const ::llvm::Instruction::BinaryOps opcode,
497  const std::vector<const Variable *> & args,
498  ::llvm::IRBuilder<> & builder);
499 
500  ::llvm::Value *
502  const rvsdg::SimpleOperation & op,
503  const std::vector<const Variable *> & args,
504  ::llvm::IRBuilder<> &);
505 
506  std::unique_ptr<Context> Context_;
507 };
508 
509 }
510 
511 #endif // JLM_LLVM_BACKEND_IPGRAPHTOLLVMCONVERTER_HPP
Call operation class.
Definition: call.hpp:249
ConstantPointerNullOperation class.
Definition: operators.hpp:430
Get address of compiled function object.
Integer attribute.
Definition: attribute.hpp:201
::llvm::Value * convert_select(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_branch(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &)
void convert_instruction(const llvm::ThreeAddressCode &tac, const llvm::ControlFlowGraphNode *node)
::llvm::Value * convert_constantdatavector(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_store(const rvsdg::SimpleOperation &operation, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_fpbin(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
void convert_tacs(const tacsvector_t &tacs)
void create_switch(const ControlFlowGraphNode *node)
::llvm::Attribute::AttrKind ConvertAttributeKind(const Attribute::kind &kind)
const ::llvm::GlobalValue::LinkageTypes & convert_linkage(const llvm::Linkage &linkage)
::llvm::Value * CreateICmpInstruction(const ::llvm::CmpInst::Predicate predicate, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Attribute ConvertStringAttribute(const llvm::StringAttribute &attribute)
::llvm::Value * convert_operation(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &arguments, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_match(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_fpneg(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_valist(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &)
void CreateStoreInstruction(const Variable *address, const Variable *value, bool isVolatile, size_t alignment, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_insertelement(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
::llvm::Value * CreateBinOpInstruction(const ::llvm::Instruction::BinaryOps opcode, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
void create_terminator_instruction(const llvm::ControlFlowGraphNode *node)
::llvm::Value * convert_ptrcmp(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_alloca(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_vectorunary(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_constantvector(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &)
std::vector< ControlFlowGraphNode * > ConvertBasicBlocks(const ControlFlowGraph &controlFlowGraph, ::llvm::Function &function)
::llvm::Value * CreateLoadInstruction(const rvsdg::Type &loadedType, const Variable *address, bool isVolatile, size_t alignment, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_ctl2bits(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &)
::llvm::Value * convert_ctlconstant(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_fpcmp(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Value * ConverterIntegerConstant(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &builder)
void convert_function(const FunctionNode &node)
::llvm::Value * convert_extractelement(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_assignment(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &)
std::unique_ptr<::llvm::Module > ConvertModule(InterProceduralGraphModule &ipGraphModule, ::llvm::LLVMContext &llvmContext)
void create_return(const ControlFlowGraphNode *node)
::llvm::Value * convert_vectorbinary(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_phi(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_cast(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
::llvm::Attribute ConvertTypeAttribute(const llvm::TypeAttribute &attribute)
void create_unconditional_branch(const ControlFlowGraphNode *node)
::llvm::Value * convert_getelementptr(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &args, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_undef(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &)
::llvm::AttributeList convert_attributes(const FunctionNode &f)
static std::unique_ptr<::llvm::Module > CreateAndConvertModule(InterProceduralGraphModule &ipGraphModule, ::llvm::LLVMContext &ctx)
void create_conditional_branch(const ControlFlowGraphNode *node)
::llvm::Attribute ConvertEnumAttribute(const llvm::EnumAttribute &attribute)
void convert_cfg(ControlFlowGraph &cfg, ::llvm::Function &f)
std::vector< T > get_fpdata(const std::vector< const Variable * > &args)
::llvm::Attribute ConvertIntAttribute(const llvm::IntAttribute &attribute)
void convert_data_node(const DataNode &node)
::llvm::Value * convert(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
std::vector< T > get_bitdata(const std::vector< const Variable * > &args)
Interpret pointer as callable function.
PoisonValueOperation class.
Definition: operators.hpp:1061
String attribute.
Definition: attribute.hpp:145
Global memory state passed between functions.
std::vector< std::unique_ptr< llvm::ThreeAddressCode > > tacsvector_t
Definition: tac.hpp:202
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049