Joos1W Compiler Framework
All Classes Functions Typedefs Pages
Constant.cc
1 #include "tir/Constant.h"
2 
3 #include <iostream>
4 #include <queue>
5 
6 #include "tir/BasicBlock.h"
7 #include "tir/Type.h"
8 #include "utils/DotPrinter.h"
9 
10 namespace tir {
11 
12 ConstantInt* Constant::CreateInt(Context& ctx, uint8_t bits, uint32_t value) {
13  return ConstantInt::Create(ctx, IntegerType::get(ctx, bits), value);
14 }
15 
16 ConstantNullPointer* Constant::CreateNullPointer(Context& ctx) {
17  return ConstantNullPointer::Create(ctx);
18 }
19 
20 std::ostream& ConstantNullPointer::print(std::ostream& os) const {
21  os << "ptr* null";
22  return os;
23 }
24 
25 std::ostream& ConstantInt::print(std::ostream& os) const {
26  os << *type() << " " << zextValue();
27  return os;
28 }
29 
30 std::ostream& GlobalVariable::print(std::ostream& os) const { return os; }
31 
32 Argument::Argument(Function* parent, Type* type, unsigned index)
33  : Value{parent->ctx(), type}, parent_{parent}, index_{index} {
34  setName("arg");
35 }
36 
37 std::ostream& Argument::print(std::ostream& os) const {
38  os << *type() << " ";
39  printName(os);
40  return os;
41 }
42 
43 std::ostream& Function::print(std::ostream& os) const {
44  os << "function ";
45  if(isExternalLinkage()) os << "external ";
46  if(isNoReturn()) os << "noreturn ";
47  os << *getReturnType() << " "
48  << "@" << name() << "(";
49  bool isFirst = true;
50  for(auto* arg : args()) {
51  if(!isFirst) os << ", ";
52  isFirst = false;
53  arg->print(os);
54  }
55  os << ")";
56  if(hasBody()) {
57  os << " {\n";
58  for(auto* bb : body()) {
59  bb->print(os) << "\n";
60  }
61  os << "}\n";
62  }
63  return os;
64 }
65 
66 void Function::printDot(std::ostream& os) const {
67  utils::DotPrinter dp{os, "5"};
68  dp.startGraph();
69  std::unordered_map<BasicBlock*, int> bbMap;
70  std::vector<BasicBlock*> terms;
71  for(auto bb : body()) {
72  int id = bb->printDotNode(dp);
73  bbMap[bb] = id;
74  }
75  for(auto bb : body()) {
76  terms.clear();
77  for(auto succ : bb->successors()) terms.push_back(succ);
78  if(terms.size() == 2) {
79  dp.printConnection(bbMap[bb], ":T", bbMap[terms[0]]);
80  dp.printConnection(bbMap[bb], ":F", bbMap[terms[1]]);
81  } else {
82  for(auto term : terms) {
83  dp.printConnection(bbMap[bb], bbMap[term]);
84  }
85  }
86  }
87  dp.endGraph();
88 }
89 
90 utils::Generator<BasicBlock*> Function::reversePostOrder() const {
91  std::unordered_set<BasicBlock*> visited;
92  std::queue<BasicBlock*> next;
93  assert(hasBody() && getEntryBlock() && "Function has no entry block");
94  next.push(getEntryBlock());
95  while(!next.empty()) {
96  auto* bb = next.front();
97  next.pop();
98  if(visited.count(bb)) continue;
99  visited.insert(bb);
100  co_yield bb;
101  for(auto succ : bb->successors()) {
102  next.push(succ);
103  }
104  }
105 }
106 
107 } // namespace tir