IR and IRBuilder implementation.

main
Su Xing 3 years ago
parent 28b30ce258
commit 9f1d1628cf

@ -0,0 +1,99 @@
#include "IR.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <map>
#include <memory>
#include <unordered_set>
#include <vector>
namespace std {
//===----------------------------------------------------------------------===//
// Types
//===----------------------------------------------------------------------===//
template <> struct hash<sysy::FunctionType> {
size_t operator()(const sysy::FunctionType &type) {
auto num = 1 + type.getNumParams();
vector<sysy::Type *> buffer(1, type.getReturnType());
copy(type.getParamTypes().begin(), type.getParamTypes().end(),
back_inserter(buffer));
string bytes(reinterpret_cast<char *>(buffer.data()),
buffer.size() * sizeof(sysy::Type *));
hash<string> hasher;
return hasher(bytes);
}
};
} // namespace std
namespace sysy {
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 *> &paramTypes) {
// forward to FunctionType
return FunctionType::get(returnType, paramTypes);
}
PointerType *PointerType::get(Type *baseType) {
static std::map<Type *, PointerType> pointerTypes;
auto result = pointerTypes.try_emplace(baseType, baseType);
return &(result.first->second);
}
FunctionType *FunctionType::get(Type *returnType,
const std::vector<Type *> &paramTypes) {
static std::unordered_set<FunctionType> functionTypes;
auto result = functionTypes.emplace(returnType, paramTypes);
// STL set objects are immutable, sothe emplace method returns const_iterator.
// We are sure FunctionType pointers cannot be used to mutate the underlying
// FunctionType object because all FunctionType methods are const methods.
return const_cast<FunctionType *>(&(*result.first));
}
void Value::replaceAllUsesWith(Value *value) {
for (auto &use : uses)
use->getUser()->setOperand(use->getIndex(), value);
uses.clear();
}
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);
}
} // namespace sysy

@ -0,0 +1,97 @@
#pragma once
#include "IR.h"
#include <cassert>
#include <memory>
namespace sysy {
class IRBuilder {
private:
BasicBlock *block;
BasicBlock::iterator position;
public:
IRBuilder(BasicBlock *block) : block(block), position(block->end()) {}
IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: block(block), position(position) {}
public:
BasicBlock *getBasicBlock() const { return block; }
BasicBlock::iterator getPosition() const { return position; }
void setPosition(BasicBlock::iterator position) { this->position = position; }
public:
CallInst *createCallInst(Function *callee,
const std::vector<Value *> args = {},
const std::string &name = "") {
auto inst = new CallInst(callee, args, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UnaryInst *createUnaryInst(Instruction::Kind kind, Type *type, Value *operand,
const std::string &name = "") {
auto inst = new UnaryInst(kind, type, operand, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
BinaryInst *createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs,
Value *rhs, const std::string &name = "") {
auto inst = new BinaryInst(kind, type, lhs, rhs, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
ReturnInst *createReturnInst(Value *value = nullptr) {
auto inst = new ReturnInst(value);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UncondBrInst *createUncondBrInst(BasicBlock *block,
std::vector<Value *> args) {
auto inst = new UncondBrInst(block, args, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
CondBrInst *createCondBrInst(Value *condition, BasicBlock *thenBlock,
BasicBlock *elseBlock,
const std::vector<Value *> &thenArgs,
const std::vector<Value *> &elseArgs) {
auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs,
elseArgs, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
AllocaInst *createAllocaInst(Type *type,
const std::vector<Value *> &dims = {},
const std::string &name = "") {
auto inst = new AllocaInst(type, dims, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
LoadInst *createLoadInst(Value *pointer,
const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new LoadInst(pointer, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
StoreInst *createStoreInst(Value *value, Value *pointer,
const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new StoreInst(value, pointer, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
};
} // namespace sysy
Loading…
Cancel
Save