forked from ph7n2ofui/SysyCompiler_Arm
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
4.0 KiB
146 lines
4.0 KiB
#include "IR.h"
|
|
#include <algorithm>
|
|
#include <cassert>
|
|
#include <cstddef>
|
|
#include <iterator>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
namespace sysy {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Types
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
Type *Type::getIntType() {
|
|
static Type intType(kInt);
|
|
return &intType;
|
|
}
|
|
|
|
Type *Type::getFloatType() {
|
|
static Type floatType(kFloat);
|
|
return &floatType;
|
|
}
|
|
|
|
Type *Type::getVoidType() {
|
|
static Type voidType(kVoid);
|
|
return &voidType;
|
|
}
|
|
|
|
Type *Type::getLabelType() {
|
|
static Type labelType(kLabel);
|
|
return &labelType;
|
|
}
|
|
|
|
Type *Type::getPointerType(Type *baseType) {
|
|
// forward to PointerType
|
|
return PointerType::get(baseType);
|
|
}
|
|
|
|
Type *Type::getFunctionType(Type *returnType,
|
|
const std::vector<Type *> ¶mTypes) {
|
|
// forward to FunctionType
|
|
return FunctionType::get(returnType, paramTypes);
|
|
}
|
|
|
|
int Type::getSize() const {
|
|
switch (kind) {
|
|
case kInt:
|
|
case kFloat:
|
|
return 4;
|
|
case kLabel:
|
|
case kPointer:
|
|
case kFunction:
|
|
return 8;
|
|
case kVoid:
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
PointerType *PointerType::get(Type *baseType) {
|
|
static std::map<Type *, std::unique_ptr<PointerType>> pointerTypes;
|
|
auto iter = pointerTypes.find(baseType);
|
|
if (iter != pointerTypes.end())
|
|
return iter->second.get();
|
|
auto type = new PointerType(baseType);
|
|
assert(type);
|
|
auto result = pointerTypes.emplace(baseType, type);
|
|
return result.first->second.get();
|
|
}
|
|
|
|
FunctionType *FunctionType::get(Type *returnType,
|
|
const std::vector<Type *> ¶mTypes) {
|
|
static std::set<std::unique_ptr<FunctionType>> functionTypes;
|
|
auto iter =
|
|
std::find_if(functionTypes.begin(), functionTypes.end(),
|
|
[&](const std::unique_ptr<FunctionType> &type) -> bool {
|
|
if (returnType != type->getReturnType() or
|
|
paramTypes.size() != type->getParamTypes().size())
|
|
return false;
|
|
return std::equal(paramTypes.begin(), paramTypes.end(),
|
|
type->getParamTypes().begin());
|
|
});
|
|
if (iter != functionTypes.end())
|
|
return iter->get();
|
|
auto type = new FunctionType(returnType, paramTypes);
|
|
assert(type);
|
|
auto result = functionTypes.emplace(type);
|
|
return result.first->get();
|
|
}
|
|
|
|
void Value::replaceAllUsesWith(Value *value) {
|
|
for (auto &use : uses)
|
|
use->getUser()->setOperand(use->getIndex(), value);
|
|
uses.clear();
|
|
}
|
|
|
|
ConstantValue *ConstantValue::get(int value, const std::string &name) {
|
|
static std::map<int, std::unique_ptr<ConstantValue>> intConstants;
|
|
auto iter = intConstants.find(value);
|
|
if (iter != intConstants.end())
|
|
return iter->second.get();
|
|
auto inst = new ConstantValue(value);
|
|
assert(inst);
|
|
auto result = intConstants.emplace(value, inst);
|
|
return result.first->second.get();
|
|
}
|
|
|
|
ConstantValue *ConstantValue::get(float value, const std::string &name) {
|
|
static std::map<float, std::unique_ptr<ConstantValue>> floatConstants;
|
|
auto iter = floatConstants.find(value);
|
|
if (iter != floatConstants.end())
|
|
return iter->second.get();
|
|
auto inst = new ConstantValue(value);
|
|
assert(inst);
|
|
auto result = floatConstants.emplace(value, inst);
|
|
return result.first->second.get();
|
|
}
|
|
|
|
void User::setOperand(int index, Value *value) {
|
|
assert(index < getNumOperands());
|
|
operands[index].setValue(value);
|
|
}
|
|
|
|
void User::replaceOperand(int index, Value *value) {
|
|
assert(index < getNumOperands());
|
|
auto &use = operands[index];
|
|
use.getValue()->removeUse(&use);
|
|
use.setValue(value);
|
|
}
|
|
|
|
CallInst::CallInst(Function *callee, const std::vector<Value *> args,
|
|
BasicBlock *parent, const std::string &name)
|
|
: Instruction(kCall, callee->getReturnType(), parent, name) {
|
|
addOperand(callee);
|
|
for (auto arg : args)
|
|
addOperand(arg);
|
|
}
|
|
|
|
Function *CallInst::getCallee() {
|
|
return dynamic_cast<Function *>(getOperand(0));
|
|
}
|
|
|
|
} // namespace sysy
|