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