1 #include "tir/Instructions.h"
3 #include "tir/BasicBlock.h"
4 #include "tir/Constant.h"
9 static std::ostream& printNameOrConst(std::ostream& os,
Value* val) {
10 if(
auto* ci = dyn_cast<ConstantInt>(val)) {
13 if(!val->type()->isLabelType()) os << *val->type() <<
" ";
23 BranchInst::BranchInst(
Context& ctx,
Value* cond, BasicBlock* trueBB,
29 static_assert(
sizeof(BranchInst) ==
sizeof(
Instruction));
32 std::ostream& BranchInst::print(std::ostream& os)
const {
34 printNameOrConst(os, getChild(0)) <<
", ";
35 printNameOrConst(os, getChild(1)) <<
", ";
36 printNameOrConst(os, getChild(2));
40 BasicBlock* BranchInst::getSuccessor(
unsigned idx)
const {
41 assert(idx < 2 &&
"BranchInst::getSuccessor index out of bounds");
42 return cast<BasicBlock>(getChild(idx + 1));
51 if(ret) addChild(ret);
52 static_assert(
sizeof(ReturnInst) ==
sizeof(
Instruction));
55 std::ostream& ReturnInst::print(std::ostream& os)
const {
57 if(numChildren() > 0) {
59 printNameOrConst(os, getChild(0));
72 static_assert(
sizeof(StoreInst) ==
sizeof(
Instruction));
75 std::ostream& StoreInst::print(std::ostream& os)
const {
77 printNameOrConst(os, getChild(0)) <<
", ";
78 printNameOrConst(os, getChild(1));
88 static_assert(
sizeof(LoadInst) ==
sizeof(
Instruction));
91 std::ostream& LoadInst::print(std::ostream& os)
const {
92 printName(os) <<
" = ";
93 os <<
"load " << *type() <<
", ";
94 printNameOrConst(os, getChild(0));
103 :
Instruction{ctx, cast<FunctionType>(callee->type())->getReturnType()} {
105 args.for_each([
this](
Value* arg) { addChild(arg); });
106 static_assert(
sizeof(CallInst) ==
sizeof(
Instruction));
109 std::ostream& CallInst::print(std::ostream& os)
const {
110 if(!type()->isVoidType()) printName(os) <<
" = ";
111 os <<
"call " << getChild(0)->name() <<
"(";
112 for(
unsigned i = 1; i < numChildren(); ++i) {
113 printNameOrConst(os, getChild(i));
114 if(i != numChildren() - 1) os <<
", ";
117 if(isTerminator()) os <<
" noreturn";
121 Function* CallInst::getCallee()
const {
return cast<Function>(getChild(0)); }
123 bool CallInst::isTerminator()
const {
return getCallee()->isNoReturn(); }
133 static_assert(
sizeof(BinaryInst) ==
sizeof(
Instruction));
136 std::ostream& BinaryInst::print(std::ostream& os)
const {
137 printName(os) <<
" = ";
138 const char* name = BinOp_to_string(binop(),
"unknown");
140 for(
unsigned i = 0; name[i] !=
'\0'; ++i)
141 os <<
static_cast<
char>(tolower(name[i]));
143 os <<
" " << *type() <<
", ";
144 printNameOrConst(os, getChild(0)) <<
", ";
145 printNameOrConst(os, getChild(1));
157 static_assert(
sizeof(CmpInst) ==
sizeof(
Instruction));
160 std::ostream& CmpInst::print(std::ostream& os)
const {
161 printName(os) <<
" = cmp ";
162 auto pred = get<Predicate>();
163 const char* name = Predicate_to_string(pred,
"unknown");
165 for(
unsigned i = 0; name[i] !=
'\0'; ++i)
166 os <<
static_cast<
char>(tolower(name[i]));
168 os <<
" " << *type() <<
" ";
169 printNameOrConst(os, getChild(0)) <<
", ";
170 printNameOrConst(os, getChild(1));
180 static_assert(
sizeof(AllocaInst) ==
sizeof(
Instruction));
183 std::ostream& AllocaInst::print(std::ostream& os)
const {
184 auto allocType_ = get<
Type*>();
185 return printName(os) <<
" = "
186 <<
"alloca " << *allocType_;
196 static_assert(
sizeof(ICastInst) ==
sizeof(
Instruction));
199 std::ostream& ICastInst::print(std::ostream& os)
const {
200 printName(os) <<
" = ";
202 const char* name = CastOp_to_string(castop(),
"unknown");
204 for(
unsigned i = 0; name[i] !=
'\0'; ++i)
205 os <<
static_cast<
char>(tolower(name[i]));
207 printNameOrConst(os, getChild(0)) <<
" to " << *type() <<
"";
215 GetElementPtrInst::GetElementPtrInst(
Context& ctx,
Value* ptr,
216 StructType* structTy,
220 indices.for_each([
this](
auto* idx) { addChild(idx); });
221 static_assert(
sizeof(GetElementPtrInst) ==
sizeof(
Instruction));
224 std::ostream& GetElementPtrInst::print(std::ostream& os)
const {
225 printName(os) <<
" = ";
226 os <<
"getelementptr " << *getStructType() <<
", ";
227 printNameOrConst(os, getChild(0));
228 for(
unsigned i = 1; i < numChildren(); ++i) {
230 printNameOrConst(os, getChild(i));