Jlm
InterProceduralGraphConversion.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
12 #include <jlm/llvm/ir/ipgraph.hpp>
15 #include <jlm/llvm/ir/ssa.hpp>
16 #include <jlm/rvsdg/binary.hpp>
17 #include <jlm/rvsdg/gamma.hpp>
18 #include <jlm/rvsdg/theta.hpp>
19 #include <jlm/util/Statistics.hpp>
20 #include <jlm/util/time.hpp>
21 
22 #include <stack>
23 #include <utility>
24 
25 namespace jlm::llvm
26 {
27 
28 class VariableMap final
29 {
30 public:
31  bool
32  contains(const Variable * v) const noexcept
33  {
34  return Map_.find(v) != Map_.end();
35  }
36 
38  lookup(const Variable * v) const
39  {
40  JLM_ASSERT(contains(v));
41  return Map_.at(v);
42  }
43 
44  void
45  insert(const Variable * v, rvsdg::Output * o)
46  {
47  JLM_ASSERT(v->type() == *o->Type());
48  Map_[v] = o;
49  }
50 
51 private:
52  std::unordered_map<const Variable *, rvsdg::Output *> Map_;
53 };
54 
56 {
57 public:
59  {
60  PopRegion();
61  JLM_ASSERT(NumRegions() == 0);
62  }
63 
65  const InterProceduralGraphModule & interProceduralGraphModule,
66  rvsdg::Region & region)
67  : InterProceduralGraphModule_(interProceduralGraphModule)
68  {
69  PushRegion(region);
70  }
71 
72  size_t
73  NumRegions() const noexcept
74  {
75  JLM_ASSERT(VariableMapStack_.size() == RegionStack_.size());
76  return VariableMapStack_.size();
77  }
78 
80  VariableMap(size_t n) noexcept
81  {
82  JLM_ASSERT(n < NumRegions());
83  return *VariableMapStack_[n];
84  }
85 
87  GetTopVariableMap() noexcept
88  {
89  JLM_ASSERT(NumRegions() > 0);
90  return VariableMap(NumRegions() - 1);
91  }
92 
94  GetRegion(size_t n) noexcept
95  {
96  JLM_ASSERT(n < NumRegions());
97  return *RegionStack_[n];
98  }
99 
100  rvsdg::Region &
101  GetTopRegion() noexcept
102  {
103  JLM_ASSERT(NumRegions() > 0);
104  return GetRegion(NumRegions() - 1);
105  }
106 
107  void
109  {
110  VariableMapStack_.push_back(std::make_unique<llvm::VariableMap>());
111  RegionStack_.push_back(&region);
112  }
113 
114  void
116  {
117  VariableMapStack_.pop_back();
118  RegionStack_.pop_back();
119  }
120 
123  {
125  }
126 
127 private:
129  std::vector<std::unique_ptr<llvm::VariableMap>> VariableMapStack_;
130  std::vector<rvsdg::Region *> RegionStack_;
131 };
132 
134 {
135 public:
137 
139  const util::FilePath & sourceFileName,
140  const std::string & functionName)
141  : Statistics(Statistics::Id::ControlFlowRecovery, sourceFileName)
142  {
144  }
145 
146  void
147  Start(const ControlFlowGraph & cfg) noexcept
148  {
149  AddMeasurement(Label::NumCfgNodes, cfg.nnodes());
151  }
152 
153  void
154  End() noexcept
155  {
157  }
158 
159  static std::unique_ptr<ControlFlowRestructuringStatistics>
160  Create(const util::FilePath & sourceFileName, const std::string & functionName)
161  {
162  return std::make_unique<ControlFlowRestructuringStatistics>(sourceFileName, functionName);
163  }
164 };
165 
167 {
168 public:
169  ~AggregationStatistics() override = default;
170 
171  AggregationStatistics(const util::FilePath & sourceFileName, const std::string & functionName)
172  : Statistics(util::Statistics::Id::Aggregation, sourceFileName)
173  {
175  }
176 
177  void
178  Start(const ControlFlowGraph & cfg) noexcept
179  {
180  AddMeasurement(Label::NumCfgNodes, cfg.nnodes());
182  }
183 
184  void
185  End() noexcept
186  {
188  }
189 
190  static std::unique_ptr<AggregationStatistics>
191  Create(const util::FilePath & sourceFileName, const std::string & functionName)
192  {
193  return std::make_unique<AggregationStatistics>(sourceFileName, functionName);
194  }
195 };
196 
198 {
199 public:
200  ~AnnotationStatistics() override = default;
201 
202  AnnotationStatistics(const util::FilePath & sourceFileName, const std::string & functionName)
203  : Statistics(util::Statistics::Id::Annotation, sourceFileName)
204  {
206  }
207 
208  void
209  Start(const AggregationNode & node) noexcept
210  {
213  }
214 
215  void
216  End() noexcept
217  {
219  }
220 
221  static std::unique_ptr<AnnotationStatistics>
222  Create(const util::FilePath & sourceFileName, const std::string & functionName)
223  {
224  return std::make_unique<AnnotationStatistics>(sourceFileName, functionName);
225  }
226 };
227 
229 {
230 public:
232 
234  const util::FilePath & sourceFileName,
235  const std::string & functionName)
236  : Statistics(util::Statistics::Id::JlmToRvsdgConversion, sourceFileName)
237  {
239  }
240 
241  void
242  Start() noexcept
243  {
245  }
246 
247  void
248  End() noexcept
249  {
251  }
252 
253  static std::unique_ptr<AggregationTreeToLambdaStatistics>
254  Create(const util::FilePath & sourceFileName, const std::string & functionName)
255  {
256  return std::make_unique<AggregationTreeToLambdaStatistics>(sourceFileName, functionName);
257  }
258 };
259 
261 {
262 public:
263  ~DataNodeToDeltaStatistics() override = default;
264 
265  DataNodeToDeltaStatistics(const util::FilePath & sourceFileName, const std::string & dataNodeName)
266  : Statistics(util::Statistics::Id::DataNodeToDelta, sourceFileName)
267  {
268  AddMeasurement("DataNode", dataNodeName);
269  }
270 
271  void
272  Start(size_t numInitializationThreeAddressCodes) noexcept
273  {
274  AddMeasurement(Label::NumThreeAddressCodes, numInitializationThreeAddressCodes);
276  }
277 
278  void
279  End() noexcept
280  {
282  }
283 
284  static std::unique_ptr<DataNodeToDeltaStatistics>
285  Create(const util::FilePath & sourceFileName, const std::string & dataNodeName)
286  {
287  return std::make_unique<DataNodeToDeltaStatistics>(sourceFileName, dataNodeName);
288  }
289 };
290 
292 {
293 public:
295 
296  explicit InterProceduralGraphToRvsdgStatistics(const util::FilePath & sourceFileName)
297  : Statistics(util::Statistics::Id::RvsdgConstruction, sourceFileName)
298  {}
299 
300  void
301  Start(const InterProceduralGraphModule & interProceduralGraphModule) noexcept
302  {
303  AddMeasurement(Label::NumThreeAddressCodes, llvm::ntacs(interProceduralGraphModule));
305  }
306 
307  void
308  End(const rvsdg::Graph & graph) noexcept
309  {
311  AddMeasurement(Label::NumRvsdgNodes, rvsdg::nnodes(&graph.GetRootRegion()));
312  }
313 
314  static std::unique_ptr<InterProceduralGraphToRvsdgStatistics>
315  Create(const util::FilePath & sourceFileName)
316  {
317  return std::make_unique<InterProceduralGraphToRvsdgStatistics>(sourceFileName);
318  }
319 };
320 
322 {
323 public:
325  util::StatisticsCollector & statisticsCollector,
326  util::FilePath sourceFileName)
327  : SourceFileName_(std::move(sourceFileName)),
328  StatisticsCollector_(statisticsCollector)
329  {}
330 
331  void
333  const std::function<void(ControlFlowGraph *)> & restructureControlFlowGraph,
334  ControlFlowGraph & cfg,
335  std::string functionName)
336  {
337  auto statistics =
339 
340  if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
341  {
342  restructureControlFlowGraph(&cfg);
343  return;
344  }
345 
346  statistics->Start(cfg);
347  restructureControlFlowGraph(&cfg);
348  statistics->End();
349 
350  StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
351  }
352 
353  std::unique_ptr<AggregationNode>
355  const std::function<std::unique_ptr<AggregationNode>(ControlFlowGraph &)> &
356  aggregateControlFlowGraph,
357  ControlFlowGraph & cfg,
358  std::string functionName)
359  {
360  auto statistics = AggregationStatistics::Create(SourceFileName_, std::move(functionName));
361 
362  if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
363  return aggregateControlFlowGraph(cfg);
364 
365  statistics->Start(cfg);
366  auto aggregationTreeRoot = aggregateControlFlowGraph(cfg);
367  statistics->End();
368 
369  StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
370 
371  return aggregationTreeRoot;
372  }
373 
374  std::unique_ptr<AnnotationMap>
376  const std::function<std::unique_ptr<AnnotationMap>(const AggregationNode &)> &
377  annotateAggregationTree,
378  const AggregationNode & aggregationTreeRoot,
379  std::string functionName)
380  {
381  auto statistics = AnnotationStatistics::Create(SourceFileName_, std::move(functionName));
382 
383  if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
384  return annotateAggregationTree(aggregationTreeRoot);
385 
386  statistics->Start(aggregationTreeRoot);
387  auto demandMap = annotateAggregationTree(aggregationTreeRoot);
388  statistics->End();
389 
390  StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
391 
392  return demandMap;
393  }
394 
395  void
397  const std::function<void()> & convertAggregationTreeToLambda,
398  std::string functionName)
399  {
400  auto statistics =
402 
403  if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
404  return convertAggregationTreeToLambda();
405 
406  statistics->Start();
407  convertAggregationTreeToLambda();
408  statistics->End();
409 
410  StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
411  }
412 
413  rvsdg::Output *
415  const std::function<rvsdg::Output *()> & convertDataNodeToDelta,
416  std::string dataNodeName,
417  size_t NumInitializationThreeAddressCodes)
418  {
419  auto statistics = DataNodeToDeltaStatistics::Create(SourceFileName_, std::move(dataNodeName));
420 
421  if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
422  return convertDataNodeToDelta();
423 
424  statistics->Start(NumInitializationThreeAddressCodes);
425  auto output = convertDataNodeToDelta();
426  statistics->End();
427 
428  StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
429 
430  return output;
431  }
432 
433  std::unique_ptr<LlvmRvsdgModule>
435  const std::function<std::unique_ptr<LlvmRvsdgModule>(InterProceduralGraphModule &)> &
436  convertInterProceduralGraphModule,
437  InterProceduralGraphModule & interProceduralGraphModule)
438  {
440 
441  if (!StatisticsCollector_.GetSettings().isDemanded(statistics->GetId()))
442  return convertInterProceduralGraphModule(interProceduralGraphModule);
443 
444  statistics->Start(interProceduralGraphModule);
445  auto rvsdgModule = convertInterProceduralGraphModule(interProceduralGraphModule);
446  statistics->End(rvsdgModule->Rvsdg());
447 
448  StatisticsCollector_.CollectDemandedStatistics(std::move(statistics));
449 
450  return rvsdgModule;
451  }
452 
453 private:
456 };
457 
458 static bool
460 {
461  return ipgNode.hasBody() && !isDiscardableIfUnused(ipgNode.linkage());
462 }
463 
464 static void
466  const llvm::ThreeAddressCode & threeAddressCode,
467  rvsdg::Region &,
468  llvm::VariableMap & variableMap)
469 {
470  JLM_ASSERT(is<AssignmentOperation>(threeAddressCode.operation()));
471 
472  auto lhs = threeAddressCode.operand(0);
473  auto rhs = threeAddressCode.operand(1);
474  variableMap.insert(lhs, variableMap.lookup(rhs));
475 }
476 
477 static void
479  const llvm::ThreeAddressCode & threeAddressCode,
480  rvsdg::Region &,
481  llvm::VariableMap & variableMap)
482 {
483  JLM_ASSERT(is<SelectOperation>(threeAddressCode.operation()));
484  JLM_ASSERT(threeAddressCode.noperands() == 3 && threeAddressCode.nresults() == 1);
485 
486  auto p = variableMap.lookup(threeAddressCode.operand(0));
487  auto predicate = rvsdg::MatchOperation::Create(*p, { { 1, 1 } }, 0, 2);
488 
489  auto gamma = rvsdg::GammaNode::create(predicate, 2);
490  auto ev1 = gamma->AddEntryVar(variableMap.lookup(threeAddressCode.operand(2)));
491  auto ev2 = gamma->AddEntryVar(variableMap.lookup(threeAddressCode.operand(1)));
492  auto ex = gamma->AddExitVar({ ev1.branchArgument[0], ev2.branchArgument[1] });
493  variableMap.insert(threeAddressCode.result(0), ex.output);
494 }
495 
496 static void
498 {
499  JLM_ASSERT(is<BranchOperation>(threeAddressCode.operation()));
500  /*
501  * Nothing needs to be done. Branches are simply ignored.
502  */
503 }
504 
505 template<class TNode, class TOperation>
506 static void
508  const llvm::ThreeAddressCode & threeAddressCode,
509  rvsdg::Region & region,
510  llvm::VariableMap & variableMap)
511 {
512  std::vector<rvsdg::Output *> operands;
513  for (size_t n = 0; n < threeAddressCode.noperands(); n++)
514  {
515  auto operand = threeAddressCode.operand(n);
516  operands.push_back(variableMap.lookup(operand));
517  }
518 
519  std::unique_ptr<TOperation> operation(
520  util::assertedCast<TOperation>(threeAddressCode.operation().copy().release()));
521  auto results = TNode::Create(region, std::move(operation), operands);
522 
523  JLM_ASSERT(results.size() == threeAddressCode.nresults());
524  for (size_t n = 0; n < threeAddressCode.nresults(); n++)
525  {
526  auto result = threeAddressCode.result(n);
527  variableMap.insert(result, results[n]);
528  }
529 }
530 
531 static void
533  const llvm::ThreeAddressCode & threeAddressCode,
534  rvsdg::Region & region,
535  llvm::VariableMap & variableMap)
536 {
537  if (is<AssignmentOperation>(&threeAddressCode))
538  {
539  ConvertAssignment(threeAddressCode, region, variableMap);
540  }
541  else if (is<SelectOperation>(&threeAddressCode))
542  {
543  ConvertSelect(threeAddressCode, region, variableMap);
544  }
545  else if (is<BranchOperation>(&threeAddressCode))
546  {
547  ConvertBranch(threeAddressCode, region, variableMap);
548  }
549  else
550  {
551  std::vector<rvsdg::Output *> operands;
552  for (size_t n = 0; n < threeAddressCode.noperands(); n++)
553  operands.push_back(variableMap.lookup(threeAddressCode.operand(n)));
554 
555  auto results =
556  outputs(&rvsdg::SimpleNode::Create(region, threeAddressCode.operation().copy(), operands));
557 
558  JLM_ASSERT(results.size() == threeAddressCode.nresults());
559  for (size_t n = 0; n < threeAddressCode.nresults(); n++)
560  variableMap.insert(threeAddressCode.result(n), results[n]);
561  }
562 }
563 
564 static void
566  const ThreeAddressCodeList & basicBlock,
567  rvsdg::Region & region,
568  llvm::VariableMap & variableMap)
569 {
570  for (const auto & threeAddressCode : basicBlock)
571  ConvertThreeAddressCode(*threeAddressCode, region, variableMap);
572 }
573 
574 static void
576  const AggregationNode & aggregationNode,
577  const AnnotationMap & demandMap,
578  rvsdg::LambdaNode & lambdaNode,
579  RegionalizedVariableMap & regionalizedVariableMap);
580 
581 static void
583  const EntryAggregationNode & entryAggregationNode,
584  const AnnotationMap & demandMap,
585  rvsdg::LambdaNode & lambdaNode,
586  RegionalizedVariableMap & regionalizedVariableMap)
587 {
588  auto & demandSet = demandMap.Lookup<EntryAnnotationSet>(entryAggregationNode);
589 
590  regionalizedVariableMap.PushRegion(*lambdaNode.subregion());
591 
592  auto & outerVariableMap =
593  regionalizedVariableMap.VariableMap(regionalizedVariableMap.NumRegions() - 2);
594  auto & topVariableMap = regionalizedVariableMap.GetTopVariableMap();
595 
596  /*
597  * Add arguments
598  */
599  JLM_ASSERT(entryAggregationNode.narguments() == lambdaNode.GetFunctionArguments().size());
600  auto lambdaArgs = lambdaNode.GetFunctionArguments();
601  for (size_t n = 0; n < entryAggregationNode.narguments(); n++)
602  {
603  auto functionNodeArgument = entryAggregationNode.argument(n);
604  auto lambdaNodeArgument = lambdaArgs[n];
605 
606  topVariableMap.insert(functionNodeArgument, lambdaNodeArgument);
607  dynamic_cast<llvm::LlvmLambdaOperation &>(lambdaNode.GetOperation())
608  .SetArgumentAttributes(n, functionNodeArgument->attributes());
609  }
610 
611  /*
612  * Add dependencies and undefined values
613  */
614  for (auto & v : demandSet.TopSet_.Variables())
615  {
616  if (outerVariableMap.contains(&v))
617  {
618  topVariableMap.insert(&v, lambdaNode.AddContextVar(*outerVariableMap.lookup(&v)).inner);
619  }
620  else
621  {
622  auto value = UndefValueOperation::Create(*lambdaNode.subregion(), v.Type());
623  topVariableMap.insert(&v, value);
624  }
625  }
626 }
627 
628 static void
630  const ExitAggregationNode & exitAggregationNode,
631  const AnnotationMap &,
632  rvsdg::LambdaNode & lambdaNode,
633  RegionalizedVariableMap & regionalizedVariableMap)
634 {
635  std::vector<rvsdg::Output *> results;
636  for (const auto & result : exitAggregationNode)
637  {
638  JLM_ASSERT(regionalizedVariableMap.GetTopVariableMap().contains(result));
639  results.push_back(regionalizedVariableMap.GetTopVariableMap().lookup(result));
640  }
641 
642  regionalizedVariableMap.PopRegion();
643  lambdaNode.finalize(results);
644 }
645 
646 static void
648  const BasicBlockAggregationNode & blockAggregationNode,
649  const AnnotationMap &,
651  RegionalizedVariableMap & regionalizedVariableMap)
652 {
654  blockAggregationNode.tacs(),
655  regionalizedVariableMap.GetTopRegion(),
656  regionalizedVariableMap.GetTopVariableMap());
657 }
658 
659 static void
661  const LinearAggregationNode & linearAggregationNode,
662  const AnnotationMap & demandMap,
663  rvsdg::LambdaNode & lambdaNode,
664  RegionalizedVariableMap & regionalizedVariableMap)
665 {
666  for (const auto & child : linearAggregationNode)
667  ConvertAggregationNode(child, demandMap, lambdaNode, regionalizedVariableMap);
668 }
669 
670 static void
672  const BranchAggregationNode & branchAggregationNode,
673  const AnnotationMap & demandMap,
674  rvsdg::LambdaNode & lambdaNode,
675  RegionalizedVariableMap & regionalizedVariableMap)
676 {
677  JLM_ASSERT(is<LinearAggregationNode>(branchAggregationNode.parent()));
678 
679  /*
680  * Find predicate
681  */
682  auto split = branchAggregationNode.parent()->child(branchAggregationNode.index() - 1);
683  while (!is<BasicBlockAggregationNode>(split))
684  split = split->child(split->nchildren() - 1);
685  auto & sb = dynamic_cast<const BasicBlockAggregationNode *>(split)->tacs();
686  JLM_ASSERT(is<BranchOperation>(sb.last()->operation()));
687  auto predicate = regionalizedVariableMap.GetTopVariableMap().lookup(sb.last()->operand(0));
688 
689  auto gamma = rvsdg::GammaNode::create(predicate, branchAggregationNode.nchildren());
690 
691  /*
692  * Add gamma inputs.
693  */
694  auto & demandSet = demandMap.Lookup<BranchAnnotationSet>(branchAggregationNode);
695  std::unordered_map<const Variable *, rvsdg::Input *> gammaInputMap;
696  for (auto & v : demandSet.InputVariables().Variables())
697  gammaInputMap[&v] =
698  gamma->AddEntryVar(regionalizedVariableMap.GetTopVariableMap().lookup(&v)).input;
699 
700  /*
701  * Convert subregions.
702  */
703  std::unordered_map<const Variable *, std::vector<rvsdg::Output *>> xvmap;
704  JLM_ASSERT(gamma->nsubregions() == branchAggregationNode.nchildren());
705  for (size_t n = 0; n < gamma->nsubregions(); n++)
706  {
707  regionalizedVariableMap.PushRegion(*gamma->subregion(n));
708  for (const auto & pair : gammaInputMap)
709  {
710  auto rolevar = gamma->MapInput(*pair.second);
711  if (auto entryvar = std::get_if<rvsdg::GammaNode::EntryVar>(&rolevar))
712  {
713  regionalizedVariableMap.GetTopVariableMap().insert(pair.first, entryvar->branchArgument[n]);
714  }
715  }
716 
718  *branchAggregationNode.child(n),
719  demandMap,
720  lambdaNode,
721  regionalizedVariableMap);
722 
723  for (auto & v : demandSet.OutputVariables().Variables())
724  xvmap[&v].push_back(regionalizedVariableMap.GetTopVariableMap().lookup(&v));
725  regionalizedVariableMap.PopRegion();
726  }
727 
728  /*
729  * Add gamma outputs.
730  */
731  for (auto & v : demandSet.OutputVariables().Variables())
732  {
733  JLM_ASSERT(xvmap.find(&v) != xvmap.end());
734  regionalizedVariableMap.GetTopVariableMap().insert(&v, gamma->AddExitVar(xvmap[&v]).output);
735  }
736 }
737 
738 static void
740  const LoopAggregationNode & loopAggregationNode,
741  const AnnotationMap & demandMap,
742  rvsdg::LambdaNode & lambdaNode,
743  RegionalizedVariableMap & regionalizedVariableMap)
744 {
745  auto & parentRegion = regionalizedVariableMap.GetTopRegion();
746 
747  auto theta = rvsdg::ThetaNode::create(&parentRegion);
748 
749  regionalizedVariableMap.PushRegion(*theta->subregion());
750  auto & thetaVariableMap = regionalizedVariableMap.GetTopVariableMap();
751  auto & outerVariableMap =
752  regionalizedVariableMap.VariableMap(regionalizedVariableMap.NumRegions() - 2);
753 
754  /*
755  * Add loop variables
756  */
757  auto & demandSet = demandMap.Lookup<LoopAnnotationSet>(loopAggregationNode);
758  std::unordered_map<const Variable *, rvsdg::ThetaNode::LoopVar> thetaLoopVarMap;
759  for (auto & v : demandSet.LoopVariables().Variables())
760  {
761  rvsdg::Output * value = nullptr;
762  if (!outerVariableMap.contains(&v))
763  {
764  value = UndefValueOperation::Create(parentRegion, v.Type());
765  outerVariableMap.insert(&v, value);
766  }
767  else
768  {
769  value = outerVariableMap.lookup(&v);
770  }
771  auto loopvar = theta->AddLoopVar(value);
772  thetaLoopVarMap[&v] = loopvar;
773  thetaVariableMap.insert(&v, loopvar.pre);
774  }
775 
776  /*
777  * Convert loop body
778  */
779  JLM_ASSERT(loopAggregationNode.nchildren() == 1);
781  *loopAggregationNode.child(0),
782  demandMap,
783  lambdaNode,
784  regionalizedVariableMap);
785 
786  /*
787  * Update loop variables
788  */
789  for (auto & v : demandSet.LoopVariables().Variables())
790  {
791  JLM_ASSERT(thetaLoopVarMap.find(&v) != thetaLoopVarMap.end());
792  thetaLoopVarMap[&v].post->divert_to(thetaVariableMap.lookup(&v));
793  }
794 
795  /*
796  * Find predicate
797  */
798  auto lblock = loopAggregationNode.child(0);
799  while (lblock->nchildren() != 0)
800  lblock = lblock->child(lblock->nchildren() - 1);
801  JLM_ASSERT(is<BasicBlockAggregationNode>(lblock));
802  auto & bb = static_cast<const BasicBlockAggregationNode *>(lblock)->tacs();
803  JLM_ASSERT(is<BranchOperation>(bb.last()->operation()));
804  auto predicate = bb.last()->operand(0);
805 
806  /*
807  * Update variable map
808  */
809  theta->set_predicate(thetaVariableMap.lookup(predicate));
810  regionalizedVariableMap.PopRegion();
811  for (auto & v : demandSet.LoopVariables().Variables())
812  {
813  JLM_ASSERT(outerVariableMap.contains(&v));
814  outerVariableMap.insert(&v, thetaLoopVarMap[&v].output);
815  }
816 }
817 
818 static void
820  const AggregationNode & aggregationNode,
821  const AnnotationMap & demandMap,
822  rvsdg::LambdaNode & lambdaNode,
823  RegionalizedVariableMap & regionalizedVariableMap)
824 {
825  if (auto entryNode = dynamic_cast<const EntryAggregationNode *>(&aggregationNode))
826  {
827  Convert(*entryNode, demandMap, lambdaNode, regionalizedVariableMap);
828  }
829  else if (auto exitNode = dynamic_cast<const ExitAggregationNode *>(&aggregationNode))
830  {
831  Convert(*exitNode, demandMap, lambdaNode, regionalizedVariableMap);
832  }
833  else if (auto blockNode = dynamic_cast<const BasicBlockAggregationNode *>(&aggregationNode))
834  {
835  Convert(*blockNode, demandMap, lambdaNode, regionalizedVariableMap);
836  }
837  else if (const auto linearNode = dynamic_cast<const LinearAggregationNode *>(&aggregationNode))
838  {
839  Convert(*linearNode, demandMap, lambdaNode, regionalizedVariableMap);
840  }
841  else if (auto branchNode = dynamic_cast<const BranchAggregationNode *>(&aggregationNode))
842  {
843  Convert(*branchNode, demandMap, lambdaNode, regionalizedVariableMap);
844  }
845  else if (auto loopNode = dynamic_cast<const LoopAggregationNode *>(&aggregationNode))
846  {
847  Convert(*loopNode, demandMap, lambdaNode, regionalizedVariableMap);
848  }
849  else
850  {
851  JLM_UNREACHABLE("Unhandled aggregation node type");
852  }
853 }
854 
855 static void
857  ControlFlowGraph & controlFlowGraph,
858  const std::string & functionName,
860 {
861  auto restructureControlFlowGraph = [](ControlFlowGraph * controlFlowGraph)
862  {
863  RestructureControlFlow(*controlFlowGraph);
864  straighten(*controlFlowGraph);
865  };
866 
867  statisticsCollector.CollectControlFlowRestructuringStatistics(
868  restructureControlFlowGraph,
869  controlFlowGraph,
870  functionName);
871 }
872 
873 static std::unique_ptr<AggregationNode>
875  ControlFlowGraph & controlFlowGraph,
876  const std::string & functionName,
878 {
879  auto aggregateControlFlowGraph = [](ControlFlowGraph & controlFlowGraph)
880  {
881  auto aggregationTreeRoot = aggregate(controlFlowGraph);
882  AggregationNode::normalize(*aggregationTreeRoot);
883 
884  return aggregationTreeRoot;
885  };
886 
887  auto aggregationTreeRoot = statisticsCollector.CollectAggregationStatistics(
888  aggregateControlFlowGraph,
889  controlFlowGraph,
890  functionName);
891 
892  return aggregationTreeRoot;
893 }
894 
895 static std::unique_ptr<AnnotationMap>
897  const AggregationNode & aggregationTreeRoot,
898  const std::string & functionName,
900 {
901  auto demandMap =
902  statisticsCollector.CollectAnnotationStatistics(Annotate, aggregationTreeRoot, functionName);
903 
904  return demandMap;
905 }
906 
907 static rvsdg::Output *
909  const AggregationNode & aggregationTreeRoot,
910  const AnnotationMap & demandMap,
911  RegionalizedVariableMap & scopedVariableMap,
912  const std::string & functionName,
913  std::shared_ptr<const rvsdg::FunctionType> functionType,
914  const Linkage & functionLinkage,
915  const AttributeSet & functionAttributes,
917 {
918  auto lambdaNode = rvsdg::LambdaNode::Create(
919  scopedVariableMap.GetTopRegion(),
920  std::make_unique<llvm::LlvmLambdaOperation>(
921  std::move(functionType),
922  functionName,
923  functionLinkage,
924  functionAttributes));
925 
926  auto convertAggregationTreeToLambda = [&]()
927  {
928  ConvertAggregationNode(aggregationTreeRoot, demandMap, *lambdaNode, scopedVariableMap);
929  };
930 
931  statisticsCollector.CollectAggregationTreeToLambdaStatistics(
932  convertAggregationTreeToLambda,
933  functionName);
934 
935  return lambdaNode->output();
936 }
937 
938 static rvsdg::Output *
940  const FunctionNode & functionNode,
941  RegionalizedVariableMap & regionalizedVariableMap,
943 {
944  auto & functionName = functionNode.name();
945  auto & controlFlowGraph = *functionNode.cfg();
946 
947  destruct_ssa(controlFlowGraph);
948  straighten(controlFlowGraph);
949  purge(controlFlowGraph);
950 
951  RestructureControlFlowGraph(controlFlowGraph, functionName, statisticsCollector);
952 
953  auto aggregationTreeRoot =
954  AggregateControlFlowGraph(controlFlowGraph, functionName, statisticsCollector);
955 
956  auto demandMap = AnnotateAggregationTree(*aggregationTreeRoot, functionName, statisticsCollector);
957 
958  auto lambdaOutput = ConvertAggregationTreeToLambda(
959  *aggregationTreeRoot,
960  *demandMap,
961  regionalizedVariableMap,
962  functionName,
963  functionNode.GetFunctionType(),
964  functionNode.linkage(),
965  functionNode.attributes(),
966  statisticsCollector);
967 
968  return lambdaOutput;
969 }
970 
971 static rvsdg::Output *
973  const FunctionNode & functionNode,
974  RegionalizedVariableMap & regionalizedVariableMap,
976 {
977  auto & region = regionalizedVariableMap.GetTopRegion();
978 
979  /*
980  * It is a function declaration as there is no control flow graph attached to the function. Simply
981  * add a function import.
982  */
983  if (functionNode.cfg() == nullptr)
984  {
985  return &LlvmGraphImport::Create(
986  *region.graph(),
987  functionNode.GetFunctionType(),
988  functionNode.GetFunctionType(),
989  functionNode.name(),
990  functionNode.linkage(),
991  true // Function imports are regarded as constant
992  );
993  }
994 
995  return ConvertControlFlowGraph(functionNode, regionalizedVariableMap, statisticsCollector);
996 }
997 
998 static rvsdg::Output *
1000  const DataNodeInit & init,
1001  rvsdg::Region & region,
1002  RegionalizedVariableMap & regionalizedVariableMap)
1003 {
1004  auto & variableMap = regionalizedVariableMap.GetTopVariableMap();
1005  for (const auto & tac : init.tacs())
1006  ConvertThreeAddressCode(*tac, region, variableMap);
1007 
1008  return variableMap.lookup(init.value());
1009 }
1010 
1011 static rvsdg::Output *
1013  const DataNode & dataNode,
1014  RegionalizedVariableMap & regionalizedVariableMap,
1015  InterProceduralGraphToRvsdgStatisticsCollector & statisticsCollector)
1016 {
1017  auto dataNodeInitialization = dataNode.initialization();
1018 
1019  auto convertDataNodeToDeltaNode = [&]() -> rvsdg::Output *
1020  {
1021  auto & interProceduralGraphModule = regionalizedVariableMap.GetInterProceduralGraphModule();
1022  auto & region = regionalizedVariableMap.GetTopRegion();
1023 
1024  /*
1025  * We have a data node without initialization. Simply add an RVSDG import.
1026  */
1027  if (!dataNodeInitialization)
1028  {
1029  return &LlvmGraphImport::Create(
1030  *region.graph(),
1031  dataNode.GetValueType(),
1033  dataNode.name(),
1034  dataNode.linkage(),
1035  dataNode.constant());
1036  }
1037 
1038  /*
1039  * data node with initialization
1040  */
1041  auto deltaNode = rvsdg::DeltaNode::Create(
1042  &region,
1044  dataNode.GetValueType(),
1045  dataNode.name(),
1046  dataNode.linkage(),
1047  dataNode.Section(),
1048  dataNode.constant()));
1049  auto & outerVariableMap = regionalizedVariableMap.GetTopVariableMap();
1050  regionalizedVariableMap.PushRegion(*deltaNode->subregion());
1051 
1052  /*
1053  * Add dependencies
1054  */
1055  for (const auto & dependency : dataNode)
1056  {
1057  auto dependencyVariable = interProceduralGraphModule.variable(dependency);
1058  auto ctxVar = deltaNode->AddContextVar(*outerVariableMap.lookup(dependencyVariable));
1059  regionalizedVariableMap.GetTopVariableMap().insert(dependencyVariable, ctxVar.inner);
1060  }
1061 
1062  auto initOutput = ConvertDataNodeInitialization(
1063  *dataNodeInitialization,
1064  *deltaNode->subregion(),
1065  regionalizedVariableMap);
1066  auto deltaOutput = &deltaNode->finalize(initOutput);
1067  regionalizedVariableMap.PopRegion();
1068 
1069  return deltaOutput;
1070  };
1071 
1072  auto deltaOutput = statisticsCollector.CollectDataNodeToDeltaStatistics(
1073  convertDataNodeToDeltaNode,
1074  dataNode.name(),
1075  dataNodeInitialization ? dataNodeInitialization->tacs().size() : 0);
1076 
1077  return deltaOutput;
1078 }
1079 
1080 static rvsdg::Output *
1082  const InterProceduralGraphNode & ipgNode,
1083  RegionalizedVariableMap & regionalizedVariableMap,
1084  InterProceduralGraphToRvsdgStatisticsCollector & statisticsCollector)
1085 {
1086  if (auto functionNode = dynamic_cast<const FunctionNode *>(&ipgNode))
1087  return ConvertFunctionNode(*functionNode, regionalizedVariableMap, statisticsCollector);
1088 
1089  if (auto dataNode = dynamic_cast<const DataNode *>(&ipgNode))
1090  return ConvertDataNode(*dataNode, regionalizedVariableMap, statisticsCollector);
1091 
1092  JLM_UNREACHABLE("This should have never happened.");
1093 }
1094 
1095 static void
1097  const std::unordered_set<const InterProceduralGraphNode *> & stronglyConnectedComponent,
1098  rvsdg::Graph & graph,
1099  RegionalizedVariableMap & regionalizedVariableMap,
1100  InterProceduralGraphToRvsdgStatisticsCollector & statisticsCollector)
1101 {
1102  auto & interProceduralGraphModule = regionalizedVariableMap.GetInterProceduralGraphModule();
1103 
1104  /*
1105  * It is a single node that is not self-recursive. We do not need a phi node to break any cycles.
1106  */
1107  if (stronglyConnectedComponent.size() == 1
1108  && !(*stronglyConnectedComponent.begin())->is_selfrecursive())
1109  {
1110  auto & ipgNode = *stronglyConnectedComponent.begin();
1111 
1112  auto output =
1113  ConvertInterProceduralGraphNode(*ipgNode, regionalizedVariableMap, statisticsCollector);
1114 
1115  auto ipgNodeVariable = interProceduralGraphModule.variable(ipgNode);
1116  regionalizedVariableMap.GetTopVariableMap().insert(ipgNodeVariable, output);
1117 
1118  if (requiresExport(*ipgNode))
1119  rvsdg::GraphExport::Create(*output, ipgNodeVariable->name());
1120 
1121  return;
1122  }
1123 
1124  rvsdg::PhiBuilder pb;
1125  pb.begin(&graph.GetRootRegion());
1126  regionalizedVariableMap.PushRegion(*pb.subregion());
1127 
1128  auto & outerVariableMap =
1129  regionalizedVariableMap.VariableMap(regionalizedVariableMap.NumRegions() - 2);
1130  auto & phiVariableMap = regionalizedVariableMap.GetTopVariableMap();
1131 
1132  /*
1133  * Add recursion variables
1134  */
1135  std::unordered_map<const Variable *, rvsdg::PhiNode::FixVar> recursionVariables;
1136  for (const auto & ipgNode : stronglyConnectedComponent)
1137  {
1138  auto recursionVariable = pb.AddFixVar(ipgNode->Type());
1139  auto ipgNodeVariable = interProceduralGraphModule.variable(ipgNode);
1140  phiVariableMap.insert(ipgNodeVariable, recursionVariable.recref);
1141  JLM_ASSERT(recursionVariables.find(ipgNodeVariable) == recursionVariables.end());
1142  recursionVariables[ipgNodeVariable] = recursionVariable;
1143  }
1144 
1145  /*
1146  * Add phi node dependencies
1147  */
1148  for (const auto & ipgNode : stronglyConnectedComponent)
1149  {
1150  for (const auto & ipgNodeDependency : *ipgNode)
1151  {
1152  auto dependencyVariable = interProceduralGraphModule.variable(ipgNodeDependency);
1153  if (recursionVariables.find(dependencyVariable) == recursionVariables.end())
1154  phiVariableMap.insert(
1155  dependencyVariable,
1156  pb.AddContextVar(*outerVariableMap.lookup(dependencyVariable)).inner);
1157  }
1158  }
1159 
1160  /*
1161  * Convert SCC nodes
1162  */
1163  for (const auto & ipgNode : stronglyConnectedComponent)
1164  {
1165  auto output =
1166  ConvertInterProceduralGraphNode(*ipgNode, regionalizedVariableMap, statisticsCollector);
1167  recursionVariables[interProceduralGraphModule.variable(ipgNode)].result->divert_to(output);
1168  }
1169 
1170  regionalizedVariableMap.PopRegion();
1171  pb.end();
1172 
1173  /*
1174  * Add phi outputs
1175  */
1176  for (const auto & ipgNode : stronglyConnectedComponent)
1177  {
1178  auto ipgNodeVariable = interProceduralGraphModule.variable(ipgNode);
1179  auto recursionVariable = recursionVariables[ipgNodeVariable];
1180  regionalizedVariableMap.GetTopVariableMap().insert(ipgNodeVariable, recursionVariable.output);
1181  if (requiresExport(*ipgNode))
1182  rvsdg::GraphExport::Create(*recursionVariable.output, ipgNodeVariable->name());
1183  }
1184 }
1185 
1186 static std::unique_ptr<LlvmRvsdgModule>
1188  InterProceduralGraphModule & interProceduralGraphModule,
1189  InterProceduralGraphToRvsdgStatisticsCollector & statisticsCollector)
1190 {
1191  auto rvsdgModule = LlvmRvsdgModule::Create(
1192  interProceduralGraphModule.source_filename(),
1193  interProceduralGraphModule.target_triple(),
1194  interProceduralGraphModule.data_layout());
1195  auto graph = &rvsdgModule->Rvsdg();
1196 
1197  RegionalizedVariableMap regionalizedVariableMap(
1198  interProceduralGraphModule,
1199  graph->GetRootRegion());
1200 
1201  auto stronglyConnectedComponents = interProceduralGraphModule.ipgraph().find_sccs();
1202  for (const auto & stronglyConnectedComponent : stronglyConnectedComponents)
1204  stronglyConnectedComponent,
1205  *graph,
1206  regionalizedVariableMap,
1207  statisticsCollector);
1208 
1209  return rvsdgModule;
1210 }
1211 
1212 std::unique_ptr<LlvmRvsdgModule>
1214  InterProceduralGraphModule & interProceduralGraphModule,
1215  util::StatisticsCollector & statisticsCollector)
1216 {
1217  InterProceduralGraphToRvsdgStatisticsCollector interProceduralGraphToRvsdgStatisticsCollector(
1218  statisticsCollector,
1219  interProceduralGraphModule.source_filename());
1220 
1221  auto convertInterProceduralGraphModule =
1222  [&](InterProceduralGraphModule & interProceduralGraphModule)
1223  {
1225  interProceduralGraphModule,
1226  interProceduralGraphToRvsdgStatisticsCollector);
1227  };
1228 
1229  auto rvsdgModule =
1230  interProceduralGraphToRvsdgStatisticsCollector.CollectInterProceduralGraphToRvsdgStatistics(
1231  convertInterProceduralGraphModule,
1232  interProceduralGraphModule);
1233 
1234  return rvsdgModule;
1235 }
1236 
1237 }
size_t nchildren() const noexcept
Definition: aggregation.hpp:69
size_t index() const noexcept
static void normalize(AggregationNode &node)
Definition: aggregation.cpp:19
AggregationNode * parent() noexcept
Definition: aggregation.hpp:91
AggregationNode * child(size_t n) const noexcept
Definition: aggregation.hpp:84
AggregationStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
static std::unique_ptr< AggregationStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
void Start(const ControlFlowGraph &cfg) noexcept
~AggregationStatistics() override=default
static std::unique_ptr< AggregationTreeToLambdaStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
AggregationTreeToLambdaStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
T & Lookup(const AggregationNode &aggregationNode) const noexcept
Definition: Annotation.hpp:504
~AnnotationStatistics() override=default
void Start(const AggregationNode &node) noexcept
static std::unique_ptr< AnnotationStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
AnnotationStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
const ThreeAddressCodeList & tacs() const noexcept
static std::unique_ptr< ControlFlowRestructuringStatistics > Create(const util::FilePath &sourceFileName, const std::string &functionName)
void Start(const ControlFlowGraph &cfg) noexcept
ControlFlowRestructuringStatistics(const util::FilePath &sourceFileName, const std::string &functionName)
const Variable * value() const noexcept
Definition: ipgraph.hpp:295
const tacsvector_t & tacs() const noexcept
Definition: ipgraph.hpp:301
void Start(size_t numInitializationThreeAddressCodes) noexcept
~DataNodeToDeltaStatistics() override=default
DataNodeToDeltaStatistics(const util::FilePath &sourceFileName, const std::string &dataNodeName)
static std::unique_ptr< DataNodeToDeltaStatistics > Create(const util::FilePath &sourceFileName, const std::string &dataNodeName)
const std::shared_ptr< const jlm::rvsdg::Type > & GetValueType() const noexcept
Definition: ipgraph.hpp:340
const std::string & name() const noexcept override
Definition: ipgraph.cpp:142
const std::string & Section() const noexcept
Definition: ipgraph.hpp:361
const llvm::Linkage & linkage() const noexcept override
Definition: ipgraph.cpp:161
const DataNodeInit * initialization() const noexcept
Definition: ipgraph.hpp:367
bool constant() const noexcept
Definition: ipgraph.hpp:355
static std::unique_ptr< DeltaOperation > Create(std::shared_ptr< const rvsdg::Type > type, const std::string &name, const llvm::Linkage &linkage, std::string section, bool constant)
Definition: delta.hpp:76
const llvm::Argument * argument(size_t index) const noexcept
size_t narguments() const noexcept
const AttributeSet & attributes() const noexcept
Definition: ipgraph.hpp:196
const std::shared_ptr< const rvsdg::FunctionType > & GetFunctionType() const noexcept
Definition: ipgraph.hpp:181
const std::string & name() const noexcept override
Definition: ipgraph.cpp:99
const llvm::Linkage & linkage() const noexcept override
Definition: ipgraph.cpp:117
llvm::ControlFlowGraph * cfg() const noexcept
Definition: ipgraph.hpp:163
const jlm::util::FilePath & source_filename() const noexcept
const std::string & target_triple() const noexcept
InterProceduralGraph & ipgraph() noexcept
const std::string & data_layout() const noexcept
virtual const llvm::Linkage & linkage() const noexcept=0
virtual bool hasBody() const noexcept=0
rvsdg::Output * CollectDataNodeToDeltaStatistics(const std::function< rvsdg::Output *()> &convertDataNodeToDelta, std::string dataNodeName, size_t NumInitializationThreeAddressCodes)
void CollectAggregationTreeToLambdaStatistics(const std::function< void()> &convertAggregationTreeToLambda, std::string functionName)
std::unique_ptr< LlvmRvsdgModule > CollectInterProceduralGraphToRvsdgStatistics(const std::function< std::unique_ptr< LlvmRvsdgModule >(InterProceduralGraphModule &)> &convertInterProceduralGraphModule, InterProceduralGraphModule &interProceduralGraphModule)
std::unique_ptr< AggregationNode > CollectAggregationStatistics(const std::function< std::unique_ptr< AggregationNode >(ControlFlowGraph &)> &aggregateControlFlowGraph, ControlFlowGraph &cfg, std::string functionName)
std::unique_ptr< AnnotationMap > CollectAnnotationStatistics(const std::function< std::unique_ptr< AnnotationMap >(const AggregationNode &)> &annotateAggregationTree, const AggregationNode &aggregationTreeRoot, std::string functionName)
void CollectControlFlowRestructuringStatistics(const std::function< void(ControlFlowGraph *)> &restructureControlFlowGraph, ControlFlowGraph &cfg, std::string functionName)
InterProceduralGraphToRvsdgStatisticsCollector(util::StatisticsCollector &statisticsCollector, util::FilePath sourceFileName)
void Start(const InterProceduralGraphModule &interProceduralGraphModule) noexcept
InterProceduralGraphToRvsdgStatistics(const util::FilePath &sourceFileName)
static std::unique_ptr< InterProceduralGraphToRvsdgStatistics > Create(const util::FilePath &sourceFileName)
std::vector< std::unordered_set< const InterProceduralGraphNode * > > find_sccs() const
Definition: ipgraph.cpp:65
static LlvmGraphImport & Create(rvsdg::Graph &graph, std::shared_ptr< const rvsdg::Type > valueType, std::shared_ptr< const rvsdg::Type > importedType, std::string name, Linkage linkage, bool isConstant=false)
Definition: RvsdgModule.hpp:81
Lambda operation.
Definition: lambda.hpp:30
static std::unique_ptr< LlvmRvsdgModule > Create(const util::FilePath &sourceFileName, const std::string &targetTriple, const std::string &dataLayout)
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
llvm::VariableMap & VariableMap(size_t n) noexcept
rvsdg::Region & GetRegion(size_t n) noexcept
llvm::VariableMap & GetTopVariableMap() noexcept
std::vector< std::unique_ptr< llvm::VariableMap > > VariableMapStack_
const InterProceduralGraphModule & GetInterProceduralGraphModule() const noexcept
const InterProceduralGraphModule & InterProceduralGraphModule_
RegionalizedVariableMap(const InterProceduralGraphModule &interProceduralGraphModule, rvsdg::Region &region)
const ThreeAddressCodeVariable * result(size_t index) const noexcept
Definition: tac.hpp:109
const Variable * operand(size_t index) const noexcept
Definition: tac.hpp:96
size_t nresults() const noexcept
Definition: tac.hpp:103
const rvsdg::SimpleOperation & operation() const noexcept
Definition: tac.hpp:84
size_t noperands() const noexcept
Definition: tac.hpp:90
static jlm::rvsdg::Output * Create(rvsdg::Region &region, std::shared_ptr< const jlm::rvsdg::Type > type)
Definition: operators.hpp:1024
bool contains(const Variable *v) const noexcept
void insert(const Variable *v, rvsdg::Output *o)
std::unordered_map< const Variable *, rvsdg::Output * > Map_
rvsdg::Output * lookup(const Variable *v) const
const jlm::rvsdg::Type & type() const noexcept
Definition: variable.hpp:56
static DeltaNode * Create(rvsdg::Region *parent, std::unique_ptr< DeltaOperation > op)
Definition: delta.hpp:313
static GammaNode * create(jlm::rvsdg::Output *predicate, size_t nalternatives)
Definition: gamma.hpp:161
static GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
Lambda node.
Definition: lambda.hpp:83
rvsdg::Output * finalize(const std::vector< jlm::rvsdg::Output * > &results)
Definition: lambda.cpp:146
std::vector< rvsdg::Output * > GetFunctionArguments() const
Definition: lambda.cpp:57
rvsdg::Region * subregion() const noexcept
Definition: lambda.hpp:138
ContextVar AddContextVar(jlm::rvsdg::Output &origin)
Adds a context/free variable to the lambda node.
Definition: lambda.cpp:131
static LambdaNode * Create(rvsdg::Region &parent, std::unique_ptr< LambdaOperation > operation)
Definition: lambda.cpp:140
LambdaOperation & GetOperation() const noexcept override
Definition: lambda.cpp:51
static Output * Create(Output &predicate, const std::unordered_map< uint64_t, uint64_t > &mapping, const uint64_t defaultAlternative, const size_t numAlternatives)
Definition: control.hpp:242
virtual std::unique_ptr< Operation > copy() const =0
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
Definition: node.hpp:366
rvsdg::Region * subregion() const noexcept
Definition: Phi.hpp:349
PhiNode * end()
Definition: Phi.cpp:270
PhiNode::ContextVar AddContextVar(jlm::rvsdg::Output &origin)
Definition: Phi.cpp:251
PhiNode::FixVar AddFixVar(std::shared_ptr< const jlm::rvsdg::Type > type)
Definition: Phi.cpp:257
void begin(rvsdg::Region *parent)
Definition: Phi.hpp:355
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
static SimpleNode & Create(Region &region, std::unique_ptr< Operation > operation, const std::vector< rvsdg::Output * > &operands)
Definition: simple-node.hpp:49
static ThetaNode * create(rvsdg::Region *parent)
Definition: theta.hpp:73
bool isDemanded(Statistics::Id id) const noexcept
Checks if a statistics is demanded.
Definition: Statistics.hpp:334
const StatisticsCollectorSettings & GetSettings() const noexcept
Definition: Statistics.hpp:511
void CollectDemandedStatistics(std::unique_ptr< Statistics > statistics)
Definition: Statistics.hpp:563
Statistics Interface.
Definition: Statistics.hpp:31
util::Timer & GetTimer(const std::string &name)
Definition: Statistics.cpp:134
Statistics(const Statistics::Id &statisticsId, util::FilePath sourceFile)
Definition: Statistics.hpp:73
util::Timer & AddTimer(std::string name)
Definition: Statistics.cpp:155
void AddMeasurement(std::string name, T value)
Definition: Statistics.hpp:174
void start() noexcept
Definition: time.hpp:54
void stop() noexcept
Definition: time.hpp:67
#define JLM_ASSERT(x)
Definition: common.hpp:16
#define JLM_UNREACHABLE(msg)
Definition: common.hpp:43
Global memory state passed between functions.
static rvsdg::Output * ConvertDataNode(const DataNode &dataNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static void ConvertStronglyConnectedComponent(const std::unordered_set< const InterProceduralGraphNode * > &stronglyConnectedComponent, rvsdg::Graph &graph, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
void destruct_ssa(ControlFlowGraph &cfg)
Definition: ssa.cpp:18
static ControlFlowGraphNode * aggregate(ControlFlowGraphNode *, ControlFlowGraphNode *, AggregationMap &)
static rvsdg::Output * ConvertFunctionNode(const FunctionNode &functionNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static std::unique_ptr< AnnotationMap > AnnotateAggregationTree(const AggregationNode &aggregationTreeRoot, const std::string &functionName, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static void ConvertBasicBlock(const ThreeAddressCodeList &basicBlock, rvsdg::Region &region, llvm::VariableMap &variableMap)
static void RestructureControlFlow(ControlFlowGraphNode &, ControlFlowGraphNode &, std::vector< TailControlledLoop > &)
static void RestructureControlFlowGraph(ControlFlowGraph &controlFlowGraph, const std::string &functionName, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
bool isDiscardableIfUnused(const Linkage linkage)
Definition: Linkage.hpp:44
static std::unique_ptr< LlvmRvsdgModule > ConvertInterProceduralGraphModule(InterProceduralGraphModule &interProceduralGraphModule, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static void ConvertThreeAddressCode(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &region, llvm::VariableMap &variableMap)
static void Convert(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &region, llvm::VariableMap &variableMap)
static rvsdg::Output * ConvertControlFlowGraph(const FunctionNode &functionNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static void ConvertAggregationNode(const AggregationNode &aggregationNode, const AnnotationMap &demandMap, rvsdg::LambdaNode &lambdaNode, RegionalizedVariableMap &regionalizedVariableMap)
static rvsdg::Output * ConvertInterProceduralGraphNode(const InterProceduralGraphNode &ipgNode, RegionalizedVariableMap &regionalizedVariableMap, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static void ConvertSelect(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &, llvm::VariableMap &variableMap)
static void ConvertBranch(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &, llvm::VariableMap &)
void straighten(ControlFlowGraph &cfg)
static bool requiresExport(const InterProceduralGraphNode &ipgNode)
size_t ntacs(const AggregationNode &root)
std::unique_ptr< AnnotationMap > Annotate(const AggregationNode &aggregationTreeRoot)
Definition: Annotation.cpp:492
static std::unique_ptr< AggregationNode > AggregateControlFlowGraph(ControlFlowGraph &controlFlowGraph, const std::string &functionName, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
static rvsdg::Output * ConvertDataNodeInitialization(const DataNodeInit &init, rvsdg::Region &region, RegionalizedVariableMap &regionalizedVariableMap)
void purge(ControlFlowGraph &cfg)
Remove all basic blocks without instructions.
static void ConvertAssignment(const llvm::ThreeAddressCode &threeAddressCode, rvsdg::Region &, llvm::VariableMap &variableMap)
static rvsdg::Output * ConvertAggregationTreeToLambda(const AggregationNode &aggregationTreeRoot, const AnnotationMap &demandMap, RegionalizedVariableMap &scopedVariableMap, const std::string &functionName, std::shared_ptr< const rvsdg::FunctionType > functionType, const Linkage &functionLinkage, const AttributeSet &functionAttributes, InterProceduralGraphToRvsdgStatisticsCollector &statisticsCollector)
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
Definition: region.cpp:629
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049
static std::vector< jlm::rvsdg::Output * > outputs(const Node *node)
Definition: node.hpp:1058
rvsdg::Output * inner
Access to bound object in subregion.
Definition: lambda.hpp:117
rvsdg::Output * inner
Access to bound object in subregion.
Definition: Phi.hpp:89
static const char * FunctionNameLabel_
Definition: Statistics.hpp:204
static const char * NumRvsdgNodes
Definition: Statistics.hpp:210
static const char * NumThreeAddressCodes
Definition: Statistics.hpp:208
static const char * Timer
Definition: Statistics.hpp:240
static const char * NumCfgNodes
Definition: Statistics.hpp:206