mirror of https://github.com/exaloop/codon.git
266 lines
5.6 KiB
C++
266 lines
5.6 KiB
C++
#include "instr.h"
|
|
|
|
#include "module.h"
|
|
#include "util/iterators.h"
|
|
|
|
namespace codon {
|
|
namespace ir {
|
|
namespace {
|
|
int findAndReplace(id_t id, codon::ir::Value *newVal,
|
|
std::vector<codon::ir::Value *> &values) {
|
|
auto replacements = 0;
|
|
for (auto &value : values) {
|
|
if (value->getId() == id) {
|
|
value = newVal;
|
|
++replacements;
|
|
}
|
|
}
|
|
return replacements;
|
|
}
|
|
} // namespace
|
|
|
|
const char Instr::NodeId = 0;
|
|
|
|
types::Type *Instr::doGetType() const { return getModule()->getVoidType(); }
|
|
|
|
const char AssignInstr::NodeId = 0;
|
|
|
|
int AssignInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
if (rhs->getId() == id) {
|
|
rhs = newValue;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int AssignInstr::doReplaceUsedVariable(id_t id, Var *newVar) {
|
|
if (lhs->getId() == id) {
|
|
lhs = newVar;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char ExtractInstr::NodeId = 0;
|
|
|
|
types::Type *ExtractInstr::doGetType() const {
|
|
auto *memberedType = cast<types::MemberedType>(val->getType());
|
|
seqassert(memberedType, "{} is not a membered type", *val->getType());
|
|
return memberedType->getMemberType(field);
|
|
}
|
|
|
|
int ExtractInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
if (val->getId() == id) {
|
|
val = newValue;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char InsertInstr::NodeId = 0;
|
|
|
|
int InsertInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
auto replacements = 0;
|
|
if (lhs->getId() == id) {
|
|
lhs = newValue;
|
|
++replacements;
|
|
}
|
|
if (rhs->getId() == id) {
|
|
rhs = newValue;
|
|
++replacements;
|
|
}
|
|
return replacements;
|
|
}
|
|
|
|
const char CallInstr::NodeId = 0;
|
|
|
|
types::Type *CallInstr::doGetType() const {
|
|
auto *funcType = cast<types::FuncType>(callee->getType());
|
|
seqassert(funcType, "{} is not a function type", *callee->getType());
|
|
return funcType->getReturnType();
|
|
}
|
|
|
|
std::vector<Value *> CallInstr::doGetUsedValues() const {
|
|
std::vector<Value *> ret(args.begin(), args.end());
|
|
ret.push_back(callee);
|
|
return ret;
|
|
}
|
|
|
|
int CallInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
auto replacements = 0;
|
|
if (callee->getId() == id) {
|
|
callee = newValue;
|
|
++replacements;
|
|
}
|
|
replacements += findAndReplace(id, newValue, args);
|
|
return replacements;
|
|
}
|
|
|
|
const char StackAllocInstr::NodeId = 0;
|
|
|
|
int StackAllocInstr::doReplaceUsedType(const std::string &name, types::Type *newType) {
|
|
if (arrayType->getName() == name) {
|
|
arrayType = newType;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char TypePropertyInstr::NodeId = 0;
|
|
|
|
types::Type *TypePropertyInstr::doGetType() const {
|
|
switch (property) {
|
|
case Property::IS_ATOMIC:
|
|
return getModule()->getBoolType();
|
|
case Property::SIZEOF:
|
|
return getModule()->getIntType();
|
|
default:
|
|
return getModule()->getVoidType();
|
|
}
|
|
}
|
|
|
|
int TypePropertyInstr::doReplaceUsedType(const std::string &name,
|
|
types::Type *newType) {
|
|
if (inspectType->getName() == name) {
|
|
inspectType = newType;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char YieldInInstr::NodeId = 0;
|
|
|
|
int YieldInInstr::doReplaceUsedType(const std::string &name, types::Type *newType) {
|
|
if (type->getName() == name) {
|
|
type = newType;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char TernaryInstr::NodeId = 0;
|
|
|
|
int TernaryInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
auto replacements = 0;
|
|
if (cond->getId() == id) {
|
|
cond = newValue;
|
|
++replacements;
|
|
}
|
|
if (trueValue->getId() == id) {
|
|
trueValue = newValue;
|
|
++replacements;
|
|
}
|
|
if (falseValue->getId() == id) {
|
|
falseValue = newValue;
|
|
++replacements;
|
|
}
|
|
return replacements;
|
|
}
|
|
|
|
const char ControlFlowInstr::NodeId = 0;
|
|
|
|
const char BreakInstr::NodeId = 0;
|
|
|
|
std::vector<Value *> BreakInstr::doGetUsedValues() const {
|
|
if (loop)
|
|
return {loop};
|
|
return {};
|
|
}
|
|
|
|
int BreakInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
if (loop && loop->getId() == id) {
|
|
auto *f = cast<Flow>(newValue);
|
|
seqassert(f, "{} is not a flow", *newValue);
|
|
loop = f;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char ContinueInstr::NodeId = 0;
|
|
|
|
std::vector<Value *> ContinueInstr::doGetUsedValues() const {
|
|
if (loop)
|
|
return {loop};
|
|
return {};
|
|
}
|
|
|
|
int ContinueInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
if (loop && loop->getId() == id) {
|
|
auto *f = cast<Flow>(newValue);
|
|
seqassert(f, "{} is not a flow", *newValue);
|
|
loop = f;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char ReturnInstr::NodeId = 0;
|
|
|
|
std::vector<Value *> ReturnInstr::doGetUsedValues() const {
|
|
if (value)
|
|
return {value};
|
|
return {};
|
|
}
|
|
|
|
int ReturnInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
auto replacements = 0;
|
|
if (value && value->getId() == id) {
|
|
setValue(newValue);
|
|
++replacements;
|
|
}
|
|
return replacements;
|
|
}
|
|
|
|
const char YieldInstr::NodeId = 0;
|
|
|
|
std::vector<Value *> YieldInstr::doGetUsedValues() const {
|
|
if (value)
|
|
return {value};
|
|
return {};
|
|
}
|
|
|
|
int YieldInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
if (value && value->getId() == id) {
|
|
setValue(newValue);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char ThrowInstr::NodeId = 0;
|
|
|
|
std::vector<Value *> ThrowInstr::doGetUsedValues() const {
|
|
if (value)
|
|
return {value};
|
|
return {};
|
|
}
|
|
|
|
int ThrowInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
if (value && value->getId() == id) {
|
|
setValue(newValue);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const char FlowInstr::NodeId = 0;
|
|
|
|
int FlowInstr::doReplaceUsedValue(id_t id, Value *newValue) {
|
|
auto replacements = 0;
|
|
if (flow->getId() == id) {
|
|
auto *f = cast<Flow>(newValue);
|
|
seqassert(f, "{} is not a flow", *newValue);
|
|
setFlow(f);
|
|
++replacements;
|
|
}
|
|
if (val->getId() == id) {
|
|
setValue(newValue);
|
|
++replacements;
|
|
}
|
|
return replacements;
|
|
}
|
|
|
|
} // namespace ir
|
|
} // namespace codon
|