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 FreezeOperation;
40 class CallOperation;
41 class LoadNonVolatileOperation;
42 class LoadVolatileOperation;
43 class StoreVolatileOperation;
44 class ConstantDataArray;
45 class ConstantArrayOperation;
46 class ConstantAggregateZeroOperation;
47 class ConstantStruct;
48 class ConstantPointerNullOperation;
49 class ShuffleVectorOperation;
50 class VectorSelectOperation;
51 class MallocOperation;
52 class FreeOperation;
53 class MemCpyNonVolatileOperation;
54 class MemCpyVolatileOperation;
55 class MemSetNonVolatileOperation;
56 class MemoryStateMergeOperation;
57 class MemoryStateSplitOperation;
58 class LambdaEntryMemoryStateSplitOperation;
59 class CallEntryMemoryStateMergeOperation;
60 class CallExitMemoryStateSplitOperation;
61 class ControlFlowGraphNode;
62 class ExtractValueOperation;
63 class FunctionNode;
64 class InsertValueOperation;
65 class InterProceduralGraphModule;
66 class LambdaExitMemoryStateMergeOperation;
67 class PointerToFunctionOperation;
68 class ThreeAddressCode;
69 class Variable;
70 
72 {
73  class Context;
74 
75 public:
77 
79 
81 
83 
85  operator=(const IpGraphToLlvmConverter &) = delete;
86 
88  operator=(IpGraphToLlvmConverter &&) = delete;
89 
90  // FIXME: InterProceduralGraphModule should be const, but we still need to create variables to
91  // translate expressions.
92  std::unique_ptr<::llvm::Module>
93  ConvertModule(InterProceduralGraphModule & ipGraphModule, ::llvm::LLVMContext & llvmContext);
94 
95  static ::llvm::Attribute::AttrKind
96  ConvertAttributeKind(const Attribute::kind & kind);
97 
98  static std::unique_ptr<::llvm::Module>
99  CreateAndConvertModule(InterProceduralGraphModule & ipGraphModule, ::llvm::LLVMContext & ctx);
100 
101 private:
102  void
103  convert_ipgraph();
104 
105  const ::llvm::GlobalValue::LinkageTypes &
106  convert_linkage(const llvm::Linkage & linkage);
107 
108  void
109  convert_data_node(const DataNode & node);
110 
111  void
112  convert_function(const FunctionNode & node);
113 
114  void
115  convert_cfg(ControlFlowGraph & cfg, ::llvm::Function & f);
116 
117  std::vector<ControlFlowGraphNode *>
118  ConvertBasicBlocks(const ControlFlowGraph & controlFlowGraph, ::llvm::Function & function);
119 
121  convert_attributes(const FunctionNode & f);
122 
123  ::llvm::AttributeSet
124  convert_attributes(const AttributeSet & attributeSet);
125 
127  convertAttributeList(const AttributeList & attributeList);
128 
129  ::llvm::Attribute
130  ConvertStringAttribute(const llvm::StringAttribute & attribute);
131 
132  ::llvm::Attribute
133  ConvertTypeAttribute(const llvm::TypeAttribute & attribute);
134 
135  ::llvm::Attribute
136  ConvertIntAttribute(const llvm::IntAttribute & attribute);
137 
138  ::llvm::Attribute
139  ConvertEnumAttribute(const llvm::EnumAttribute & attribute);
140 
141  void
143 
144  void
145  create_switch(const ControlFlowGraphNode * node);
146 
147  void
149 
150  void
152 
153  void
154  create_return(const ControlFlowGraphNode * node);
155 
156  void
157  convert_tacs(const tacsvector_t & tacs);
158 
159  void
161 
172  ::llvm::Value *
174  const rvsdg::SimpleOperation & op,
175  const rvsdg::SimpleOperation & originalOp,
176  const std::vector<const Variable *> & arguments,
177  ::llvm::IRBuilder<> & builder);
178 
179  template<class OP>
180  ::llvm::Value *
182  const rvsdg::SimpleOperation & op,
183  const std::vector<const Variable *> & operands,
184  ::llvm::IRBuilder<> & builder);
185 
186  ::llvm::Value *
187  convert(
189  const std::vector<const Variable *> & operands,
190  ::llvm::IRBuilder<> &);
191 
192  ::llvm::Value *
193  convert(
195  const std::vector<const Variable *> & operands,
196  ::llvm::IRBuilder<> &);
197 
198  ::llvm::Value *
199  convert(
201  const std::vector<const Variable *> &,
202  ::llvm::IRBuilder<> &);
203 
204  ::llvm::Value *
205  convert(
207  const std::vector<const Variable *> &,
208  ::llvm::IRBuilder<> &);
209 
210  ::llvm::Value *
211  convert(
213  const std::vector<const Variable *> &,
214  ::llvm::IRBuilder<> &);
215 
216  ::llvm::Value *
217  convert(
219  const std::vector<const Variable *> &,
220  ::llvm::IRBuilder<> &);
221 
222  ::llvm::Value *
223  convert(
225  const std::vector<const Variable *> &,
226  ::llvm::IRBuilder<> &);
227 
228  ::llvm::Value *
229  convert(
231  const std::vector<const Variable *> &,
232  ::llvm::IRBuilder<> &);
233 
234  ::llvm::Value *
235  convert(
236  const MemCpyVolatileOperation &,
237  const std::vector<const Variable *> & operands,
238  ::llvm::IRBuilder<> & builder);
239 
240  ::llvm::Value *
241  convert(
243  const std::vector<const Variable *> & operands,
244  ::llvm::IRBuilder<> & builder);
245 
246  ::llvm::Value *
248  const rvsdg::SimpleOperation &,
249  const std::vector<const Variable *> &,
250  ::llvm::IRBuilder<> &);
251 
252  ::llvm::Value *
253  convert(
254  const FreeOperation & op,
255  const std::vector<const Variable *> & args,
256  ::llvm::IRBuilder<> & builder);
257 
258  ::llvm::Value *
259  convert(
260  const MallocOperation & op,
261  const std::vector<const Variable *> & args,
262  ::llvm::IRBuilder<> & builder);
263 
264  ::llvm::Value *
265  convert(
266  const ExtractValueOperation & op,
267  const std::vector<const Variable *> & operands,
268  ::llvm::IRBuilder<> & builder);
269 
270  ::llvm::Value *
272  const InsertValueOperation & operation,
273  const std::vector<const Variable *> & operands,
274  ::llvm::IRBuilder<> & builder) const;
275 
276  template<::llvm::Instruction::CastOps OPCODE>
277  ::llvm::Value *
279  const rvsdg::SimpleOperation & op,
280  const rvsdg::SimpleOperation & originalOp,
281  const std::vector<const Variable *> & operands,
282  ::llvm::IRBuilder<> & builder);
283 
284  ::llvm::Value *
285  convert(
286  const VectorSelectOperation &,
287  const std::vector<const Variable *> & operands,
288  ::llvm::IRBuilder<> & builder);
289 
290  ::llvm::Value *
292  const rvsdg::SimpleOperation & op,
293  const rvsdg::SimpleOperation & originalOp,
294  const std::vector<const Variable *> & operands,
295  ::llvm::IRBuilder<> & builder);
296 
297  ::llvm::Value *
299  const rvsdg::SimpleOperation & op,
300  const rvsdg::SimpleOperation & originalOp,
301  const std::vector<const Variable *> & operands,
302  ::llvm::IRBuilder<> & builder);
303 
304  ::llvm::Value *
306  const rvsdg::SimpleOperation & op,
307  const std::vector<const Variable *> & operands,
308  ::llvm::IRBuilder<> & builder);
309 
310  ::llvm::Value *
311  convert(
312  const ShuffleVectorOperation & op,
313  const std::vector<const Variable *> & operands,
314  ::llvm::IRBuilder<> & builder);
315 
316  ::llvm::Value *
318  const rvsdg::SimpleOperation & op,
319  const std::vector<const Variable *> & args,
320  ::llvm::IRBuilder<> & builder);
321 
322  ::llvm::Value *
324  const rvsdg::SimpleOperation & op,
325  const std::vector<const Variable *> & operands,
326  ::llvm::IRBuilder<> & builder);
327 
328  ::llvm::Value *
330  const rvsdg::SimpleOperation & op,
331  const std::vector<const Variable *> & operands,
332  ::llvm::IRBuilder<> &);
333 
334  ::llvm::Value *
336  const rvsdg::SimpleOperation & op,
337  const std::vector<const Variable *> & args,
338  ::llvm::IRBuilder<> &);
339 
340  ::llvm::Value *
342  const rvsdg::SimpleOperation & op,
343  const std::vector<const Variable *> & operands,
344  ::llvm::IRBuilder<> & builder);
345 
346  ::llvm::Value *
347  convert(
348  const ConstantPointerNullOperation & operation,
349  const std::vector<const Variable *> &,
350  ::llvm::IRBuilder<> &);
351 
352  ::llvm::Value *
353  convert(
354  const ConstantStruct & op,
355  const std::vector<const Variable *> & args,
356  ::llvm::IRBuilder<> &);
357 
358  ::llvm::Value *
360  const rvsdg::SimpleOperation & op,
361  const std::vector<const Variable *> &,
362  ::llvm::IRBuilder<> &);
363 
364  ::llvm::Value *
366  const rvsdg::SimpleOperation & op,
367  const std::vector<const Variable *> & args,
368  ::llvm::IRBuilder<> & builder);
369 
370  ::llvm::Value *
372  const rvsdg::SimpleOperation & op,
373  const std::vector<const Variable *> & args,
374  ::llvm::IRBuilder<> & builder);
375 
376  ::llvm::Value *
378  const rvsdg::SimpleOperation & op,
379  const std::vector<const Variable *> & args,
380  ::llvm::IRBuilder<> & builder);
381 
382  ::llvm::Value *
384  const rvsdg::SimpleOperation & op,
385  const std::vector<const Variable *> & args,
386  ::llvm::IRBuilder<> & builder);
387 
388  ::llvm::Value *
389  convert(
391  const std::vector<const Variable *> &,
392  ::llvm::IRBuilder<> &);
393 
394  ::llvm::Value *
395  convert(
396  const ConstantArrayOperation & op,
397  const std::vector<const Variable *> & operands,
398  ::llvm::IRBuilder<> &);
399 
400  ::llvm::Value *
401  convert(
402  const ConstantDataArray & op,
403  const std::vector<const Variable *> & operands,
404  ::llvm::IRBuilder<> & builder);
405 
406  template<typename T>
407  std::vector<T>
408  get_fpdata(const std::vector<const Variable *> & args);
409 
410  template<typename T>
411  std::vector<T>
412  get_bitdata(const std::vector<const Variable *> & args);
413 
414  ::llvm::Value *
416  const rvsdg::SimpleOperation & op,
417  const std::vector<const Variable *> & args,
418  ::llvm::IRBuilder<> & builder);
419 
420  ::llvm::Value *
422  const rvsdg::SimpleOperation & op,
423  const std::vector<const Variable *> & args,
424  ::llvm::IRBuilder<> & builder);
425 
426  ::llvm::Value *
427  convert(
428  const StoreVolatileOperation & operation,
429  const std::vector<const Variable *> & operands,
430  ::llvm::IRBuilder<> & builder);
431 
432  ::llvm::Value *
434  const rvsdg::SimpleOperation & operation,
435  const std::vector<const Variable *> & operands,
436  ::llvm::IRBuilder<> & builder);
437 
438  void
440  const Variable * address,
441  const Variable * value,
442  bool isVolatile,
443  size_t alignment,
444  ::llvm::IRBuilder<> & builder);
445 
446  ::llvm::Value *
447  convert(
448  const LoadVolatileOperation & operation,
449  const std::vector<const Variable *> & operands,
450  ::llvm::IRBuilder<> & builder);
451 
452  ::llvm::Value *
453  convert(
454  const LoadNonVolatileOperation & operation,
455  const std::vector<const Variable *> & operands,
456  ::llvm::IRBuilder<> & builder);
457 
458  ::llvm::Value *
460  const rvsdg::Type & loadedType,
461  const Variable * address,
462  bool isVolatile,
463  size_t alignment,
464  ::llvm::IRBuilder<> & builder);
465 
466  ::llvm::Value *
467  convert_phi(
468  const rvsdg::SimpleOperation & op,
469  const std::vector<const Variable *> &,
470  ::llvm::IRBuilder<> & builder);
471 
472  ::llvm::Value *
474  const rvsdg::SimpleOperation & op,
475  const std::vector<const Variable *> &,
476  ::llvm::IRBuilder<> &);
477 
478  ::llvm::Value *
480  const rvsdg::SimpleOperation & op,
481  const std::vector<const Variable *> & args,
482  ::llvm::IRBuilder<> & builder);
483 
484  ::llvm::Value *
485  convert(
486  const CallOperation & op,
487  const std::vector<const Variable *> & args,
488  ::llvm::IRBuilder<> & builder);
489 
490  ::llvm::Value *
491  convert(
492  const PoisonValueOperation & operation,
493  const std::vector<const Variable *> &,
494  ::llvm::IRBuilder<> &);
495 
496  ::llvm::Value *
497  convert(
498  const FreezeOperation & operation,
499  const std::vector<const Variable *> &,
500  ::llvm::IRBuilder<> &);
501 
502  ::llvm::Value *
504  const rvsdg::SimpleOperation & op,
505  const std::vector<const Variable *> &,
506  ::llvm::IRBuilder<> &);
507 
508  ::llvm::Value *
509  convert(
510  const ConstantFP & op,
511  const std::vector<const Variable *> &,
512  ::llvm::IRBuilder<> & builder);
513 
514  ::llvm::Value *
516  const rvsdg::SimpleOperation & op,
517  const std::vector<const Variable *> &,
518  ::llvm::IRBuilder<> & builder);
519 
520  ::llvm::Value *
522  const rvsdg::SimpleOperation & op,
523  const std::vector<const Variable *> &,
524  ::llvm::IRBuilder<> & builder);
525 
526  ::llvm::Value *
528  const ::llvm::CmpInst::Predicate predicate,
529  const std::vector<const Variable *> & args,
530  ::llvm::IRBuilder<> & builder);
531 
532  ::llvm::Value *
534  const ::llvm::Instruction::BinaryOps opcode,
535  const std::vector<const Variable *> & args,
536  ::llvm::IRBuilder<> & builder);
537 
538  ::llvm::Value *
540  const rvsdg::SimpleOperation & op,
541  const std::vector<const Variable *> & args,
542  ::llvm::IRBuilder<> &);
543 
544  std::unique_ptr<Context> Context_;
545 };
546 
547 }
548 
549 #endif // JLM_LLVM_BACKEND_IPGRAPHTOLLVMCONVERTER_HPP
Call operation class.
Definition: call.hpp:251
ConstantPointerNullOperation class.
Definition: operators.hpp:432
FreezeOperation class.
Definition: operators.hpp:1160
Get address of compiled function object.
Integer attribute.
Definition: attribute.hpp:201
::llvm::AttributeList convertAttributeList(const AttributeList &attributeList)
::llvm::Value * convertInsertValueOperation(const InsertValueOperation &operation, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder) const
::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 * convertMemsetNonVolatileOperation(const rvsdg::SimpleOperation &, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &)
::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_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_constantvector(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &)
::llvm::Value * convert_vectorunary(const rvsdg::SimpleOperation &op, const rvsdg::SimpleOperation &originalOp, const std::vector< const Variable * > &operands, ::llvm::IRBuilder<> &builder)
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_cast(const rvsdg::SimpleOperation &op, const rvsdg::SimpleOperation &originalOp, const std::vector< const Variable * > &operands, ::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<> &)
::llvm::Value * convert_operation(const rvsdg::SimpleOperation &op, const rvsdg::SimpleOperation &originalOp, const std::vector< const Variable * > &arguments, ::llvm::IRBuilder<> &builder)
std::unique_ptr<::llvm::Module > ConvertModule(InterProceduralGraphModule &ipGraphModule, ::llvm::LLVMContext &llvmContext)
void create_return(const ControlFlowGraphNode *node)
::llvm::Value * convert_phi(const rvsdg::SimpleOperation &op, const std::vector< const Variable * > &, ::llvm::IRBuilder<> &builder)
::llvm::Value * convert_vectorbinary(const rvsdg::SimpleOperation &op, const rvsdg::SimpleOperation &originalOp, 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:1092
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