更新IR结构,重写IRBuilder

This commit is contained in:
rain2133
2025-06-21 12:53:41 +08:00
parent c54543bff3
commit 30f89bba23
3 changed files with 1869 additions and 939 deletions

View File

@ -1,310 +1,719 @@
#pragma once
#include "IR.h"
#include <algorithm>
#include <cassert>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include "IRBuilder.h"
/**
* @file IR.cpp
*
* @brief 定义IR相关类型与操作的源文件
*/
namespace sysy {
class IRBuilder {
private:
unsigned labelIndex; ///< 基本块标签编号
unsigned tmpIndex; ///< 临时变量编号
//===----------------------------------------------------------------------===//
// Types
//===----------------------------------------------------------------------===//
BasicBlock *block; ///< 当前基本块
BasicBlock::iterator position; ///< 当前基本块指令列表位置的迭代器
auto Type::getIntType() -> Type * {
static Type intType(kInt);
return &intType;
}
std::vector<BasicBlock *> trueBlocks; ///< true分支基本块列表
std::vector<BasicBlock *> falseBlocks; ///< false分支基本块列表
auto Type::getFloatType() -> Type * {
static Type floatType(kFloat);
return &floatType;
}
std::vector<BasicBlock *> breakBlocks; ///< break目标块列表
std::vector<BasicBlock *> continueBlocks; ///< continue目标块列表
auto Type::getVoidType() -> Type * {
static Type voidType(kVoid);
return &voidType;
}
public:
IRBuilder() : labelIndex(0), tmpIndex(0), block(nullptr) {}
explicit IRBuilder(BasicBlock *block) : labelIndex(0), tmpIndex(0), block(block), position(block->end()) {}
IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: labelIndex(0), tmpIndex(0), block(block), position(position) {}
auto Type::getLabelType() -> Type * {
static Type labelType(kLabel);
return &labelType;
}
public:
unsigned getLabelIndex() { return labelIndex++; }
unsigned getTmpIndex() { return tmpIndex++; }
BasicBlock *getBasicBlock() const { return block; }
BasicBlock::iterator getPosition() const { return position; }
void setPosition(BasicBlock *block, BasicBlock::iterator position) {
this->block = block;
this->position = position;
auto Type::getPointerType(Type *baseType) -> Type * {
// forward to PointerType
return PointerType::get(baseType);
}
auto Type::getFunctionType(Type *returnType, const std::vector<Type *> &paramTypes) -> Type * {
// forward to FunctionType
return FunctionType::get(returnType, paramTypes);
}
auto Type::getSize() const -> unsigned {
switch (kind) {
case kInt:
case kFloat:
return 4;
case kLabel:
case kPointer:
case kFunction:
return 8;
case kVoid:
return 0;
}
void setPosition(BasicBlock::iterator position) { this->position = position; }
return 0;
}
// 控制流管理函数
BasicBlock *getBreakBlock() const { return breakBlocks.back(); }
BasicBlock *popBreakBlock() {
auto result = breakBlocks.back();
breakBlocks.pop_back();
return result;
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();
}
BasicBlock *getContinueBlock() const { return continueBlocks.back(); }
BasicBlock *popContinueBlock() {
auto result = continueBlocks.back();
continueBlocks.pop_back();
return result;
}
BasicBlock *getTrueBlock() const { return trueBlocks.back(); }
BasicBlock *getFalseBlock() const { return falseBlocks.back(); }
BasicBlock *popTrueBlock() {
auto result = trueBlocks.back();
trueBlocks.pop_back();
return result;
}
BasicBlock *popFalseBlock() {
auto result = falseBlocks.back();
falseBlocks.pop_back();
return result;
}
void pushBreakBlock(BasicBlock *block) { breakBlocks.push_back(block); }
void pushContinueBlock(BasicBlock *block) { continueBlocks.push_back(block); }
void pushTrueBlock(BasicBlock *block) { trueBlocks.push_back(block); }
void pushFalseBlock(BasicBlock *block) { falseBlocks.push_back(block); }
auto type = new PointerType(baseType);
assert(type);
auto result = pointerTypes.emplace(baseType, type);
return result.first->second.get();
}
public:
// 指令创建函数
Instruction *insertInst(Instruction *inst) {
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
FunctionType*FunctionType::get(Type *returnType, const std::vector<Type *> &paramTypes) {
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() ||
paramTypes.size() != static_cast<size_t>(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) {
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) {
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();
}
auto Function::getCalleesWithNoExternalAndSelf() -> std::set<Function *> {
std::set<Function *> result;
for (auto callee : callees) {
if (parent->getExternalFunctions().count(callee->getName()) == 0U && callee != this) {
result.insert(callee);
}
}
return result;
}
Function * Function::clone(const std::string &suffix) const {
std::stringstream ss;
std::map<BasicBlock *, BasicBlock *> oldNewBlockMap;
IRBuilder builder;
auto newFunction = new Function(parent, type, name);
newFunction->getEntryBlock()->setName(blocks.front()->getName());
oldNewBlockMap.emplace(blocks.front().get(), newFunction->getEntryBlock());
auto oldBlockListIter = std::next(blocks.begin());
while (oldBlockListIter != blocks.end()) {
auto newBlock = newFunction->addBasicBlock(oldBlockListIter->get()->getName());
oldNewBlockMap.emplace(oldBlockListIter->get(), newBlock);
oldBlockListIter++;
}
UnaryInst *createUnaryInst(Instruction::Kind kind, Type *type, Value *operand,
const std::string &name = "") {
auto inst = new UnaryInst(kind, type, operand, block, name);
return static_cast<UnaryInst*>(insertInst(inst));
for (const auto &oldNewBlockItem : oldNewBlockMap) {
auto oldBlock = oldNewBlockItem.first;
auto newBlock = oldNewBlockItem.second;
for (const auto &oldPred : oldBlock->getPredecessors()) {
newBlock->addPredecessor(oldNewBlockMap.at(oldPred));
}
for (const auto &oldSucc : oldBlock->getSuccessors()) {
newBlock->addSuccessor(oldNewBlockMap.at(oldSucc));
}
}
UnaryInst *createNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNeg, Type::getIntType(), operand, name);
std::map<Value *, Value *> oldNewValueMap;
std::map<Value *, bool> isAddedToCreate;
std::map<Value *, bool> isCreated;
std::queue<Value *> toCreate;
for (const auto &oldBlock : blocks) {
for (const auto &inst : oldBlock->getInstructions()) {
isAddedToCreate.emplace(inst.get(), false);
isCreated.emplace(inst.get(), false);
}
}
for (const auto &oldBlock : blocks) {
for (const auto &inst : oldBlock->getInstructions()) {
for (const auto &valueUse : inst->getOperands()) {
auto value = valueUse->getValue();
if (oldNewValueMap.find(value) == oldNewValueMap.end()) {
auto oldAllocInst = dynamic_cast<AllocaInst *>(value);
if (oldAllocInst != nullptr) {
std::vector<Value *> dims;
for (const auto &dim : oldAllocInst->getDims()) {
dims.emplace_back(dim->getValue());
}
ss << oldAllocInst->getName() << suffix;
auto newAllocInst =
new AllocaInst(oldAllocInst->getType(), dims, oldNewBlockMap.at(oldAllocInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldAllocInst, newAllocInst);
if (isAddedToCreate.find(oldAllocInst) == isAddedToCreate.end()) {
isAddedToCreate.emplace(oldAllocInst, true);
} else {
isAddedToCreate.at(oldAllocInst) = true;
}
if (isCreated.find(oldAllocInst) == isCreated.end()) {
isCreated.emplace(oldAllocInst, true);
} else {
isCreated.at(oldAllocInst) = true;
}
}
}
}
if (inst->getKind() == Instruction::kAlloca) {
if (oldNewValueMap.find(inst.get()) == oldNewValueMap.end()) {
auto oldAllocInst = dynamic_cast<AllocaInst *>(inst.get());
std::vector<Value *> dims;
for (const auto &dim : oldAllocInst->getDims()) {
dims.emplace_back(dim->getValue());
}
ss << oldAllocInst->getName() << suffix;
auto newAllocInst =
new AllocaInst(oldAllocInst->getType(), dims, oldNewBlockMap.at(oldAllocInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldAllocInst, newAllocInst);
if (isAddedToCreate.find(oldAllocInst) == isAddedToCreate.end()) {
isAddedToCreate.emplace(oldAllocInst, true);
} else {
isAddedToCreate.at(oldAllocInst) = true;
}
if (isCreated.find(oldAllocInst) == isCreated.end()) {
isCreated.emplace(oldAllocInst, true);
} else {
isCreated.at(oldAllocInst) = true;
}
}
}
}
}
for (const auto &oldBlock : blocks) {
for (const auto &inst : oldBlock->getInstructions()) {
for (const auto &valueUse : inst->getOperands()) {
auto value = valueUse->getValue();
if (oldNewValueMap.find(value) == oldNewValueMap.end()) {
auto globalValue = dynamic_cast<GlobalValue *>(value);
auto constVariable = dynamic_cast<ConstantVariable *>(value);
auto constantValue = dynamic_cast<ConstantValue *>(value);
auto functionValue = dynamic_cast<Function *>(value);
if (globalValue != nullptr || constantValue != nullptr || constVariable != nullptr ||
functionValue != nullptr) {
if (functionValue == this) {
oldNewValueMap.emplace(value, newFunction);
} else {
oldNewValueMap.emplace(value, value);
}
isCreated.emplace(value, true);
isAddedToCreate.emplace(value, true);
}
}
}
}
}
for (const auto &oldBlock : blocks) {
for (const auto &inst : oldBlock->getInstructions()) {
if (inst->getKind() != Instruction::kAlloca) {
bool isReady = true;
for (const auto &use : inst->getOperands()) {
auto value = use->getValue();
if (dynamic_cast<BasicBlock *>(value) == nullptr && !isCreated.at(value)) {
isReady = false;
break;
}
}
if (isReady) {
toCreate.push(inst.get());
isAddedToCreate.at(inst.get()) = true;
}
}
}
}
UnaryInst *createNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNot, Type::getIntType(), operand, name);
}
while (!toCreate.empty()) {
auto inst = dynamic_cast<Instruction *>(toCreate.front());
toCreate.pop();
UnaryInst *createFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFtoI, Type::getIntType(), operand, name);
}
UnaryInst *createBitFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kBitFtoI, Type::getIntType(), operand, name);
}
UnaryInst *createFNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNeg, Type::getFloatType(), operand, name);
}
UnaryInst *createFNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNot, Type::getIntType(), operand, name);
}
UnaryInst *createIToFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand, name);
}
UnaryInst *createBitItoFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kBitItoF, Type::getFloatType(), operand, name);
}
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);
return static_cast<BinaryInst*>(insertInst(inst));
}
BinaryInst *createAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAdd, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kSub, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kMul, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kDiv, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createRemInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kRem, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpEQ, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpNE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFAdd, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFSub, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFMul, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFDiv, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFCmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpEQ, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpNE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createAndInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAnd, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createOrInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kOr, Type::getIntType(), lhs, rhs, name);
}
CallInst *createCallInst(Function *callee, const std::vector<Value *> &args,
const std::string &name = "") {
auto inst = new CallInst(callee, args, block, name);
return static_cast<CallInst*>(insertInst(inst));
}
ReturnInst *createReturnInst(Value *value = nullptr) {
auto inst = new ReturnInst(value, block);
return static_cast<ReturnInst*>(insertInst(inst));
}
UncondBrInst *createUncondBrInst(BasicBlock *thenBlock,
const std::vector<Value *> &args) {
auto inst = new UncondBrInst(thenBlock, args, block);
return static_cast<UncondBrInst*>(insertInst(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);
return static_cast<CondBrInst*>(insertInst(inst));
}
AllocaInst *createAllocaInst(Type *type, const std::vector<Value *> &dims = {},
const std::string &name = "") {
auto inst = new AllocaInst(type, dims, block, name);
return static_cast<AllocaInst*>(insertInst(inst));
}
AllocaInst *createAllocaInstWithoutInsert(Type *type,
const std::vector<Value *> &dims = {},
BasicBlock *parent = nullptr,
const std::string &name = "") {
return new AllocaInst(type, dims, parent, name);
}
LoadInst *createLoadInst(Value *pointer, const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new LoadInst(pointer, indices, block, name);
return static_cast<LoadInst*>(insertInst(inst));
}
LaInst *createLaInst(Value *pointer, const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new LaInst(pointer, indices, block, name);
return static_cast<LaInst*>(insertInst(inst));
}
GetSubArrayInst *createGetSubArray(LVal *fatherArray,
const std::vector<Value *> &indices,
const std::string &name = "") {
assert(fatherArray->getLValNumDims() > indices.size());
std::vector<Value *> subDims;
auto dims = fatherArray->getLValDims();
auto iter = std::next(dims.begin(), indices.size());
while (iter != dims.end()) {
subDims.emplace_back(*iter);
iter++;
bool isReady = true;
for (const auto &valueUse : inst->getOperands()) {
auto value = dynamic_cast<Instruction *>(valueUse->getValue());
if (value != nullptr && !isCreated.at(value)) {
isReady = false;
break;
}
}
auto fatherArrayValue = dynamic_cast<Value *>(fatherArray);
AllocaInst * childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block);
auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block ,name);
return static_cast<GetSubArrayInst*>(insertInst(inst));
if (!isReady) {
toCreate.push(inst);
continue;
}
isCreated.at(inst) = true;
switch (inst->getKind()) {
case Instruction::kAdd:
case Instruction::kSub:
case Instruction::kMul:
case Instruction::kDiv:
case Instruction::kRem:
case Instruction::kICmpEQ:
case Instruction::kICmpNE:
case Instruction::kICmpLT:
case Instruction::kICmpGT:
case Instruction::kICmpLE:
case Instruction::kICmpGE:
case Instruction::kAnd:
case Instruction::kOr:
case Instruction::kFAdd:
case Instruction::kFSub:
case Instruction::kFMul:
case Instruction::kFDiv:
case Instruction::kFCmpEQ:
case Instruction::kFCmpNE:
case Instruction::kFCmpLT:
case Instruction::kFCmpGT:
case Instruction::kFCmpLE:
case Instruction::kFCmpGE: {
auto oldBinaryInst = dynamic_cast<BinaryInst *>(inst);
auto lhs = oldBinaryInst->getLhs();
auto rhs = oldBinaryInst->getRhs();
Value *newLhs;
Value *newRhs;
newLhs = oldNewValueMap[lhs];
newRhs = oldNewValueMap[rhs];
ss << oldBinaryInst->getName() << suffix;
auto newBinaryInst = new BinaryInst(oldBinaryInst->getKind(), oldBinaryInst->getType(), newLhs, newRhs,
oldNewBlockMap.at(oldBinaryInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldBinaryInst, newBinaryInst);
break;
}
case Instruction::kNeg:
case Instruction::kNot:
case Instruction::kFNeg:
case Instruction::kFNot:
case Instruction::kItoF:
case Instruction::kFtoI: {
auto oldUnaryInst = dynamic_cast<UnaryInst *>(inst);
auto hs = oldUnaryInst->getOperand();
Value *newHs;
newHs = oldNewValueMap.at(hs);
ss << oldUnaryInst->getName() << suffix;
auto newUnaryInst = new UnaryInst(oldUnaryInst->getKind(), oldUnaryInst->getType(), newHs,
oldNewBlockMap.at(oldUnaryInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldUnaryInst, newUnaryInst);
break;
}
case Instruction::kCall: {
auto oldCallInst = dynamic_cast<CallInst *>(inst);
std::vector<Value *> newArgumnts;
for (const auto &arg : oldCallInst->getArguments()) {
newArgumnts.emplace_back(oldNewValueMap.at(arg->getValue()));
}
ss << oldCallInst->getName() << suffix;
CallInst *newCallInst;
newCallInst =
new CallInst(oldCallInst->getCallee(), newArgumnts, oldNewBlockMap.at(oldCallInst->getParent()), ss.str());
ss.str("");
// if (oldCallInst->getCallee() != this) {
// newCallInst = new CallInst(oldCallInst->getCallee(), newArgumnts,
// oldNewBlockMap.at(oldCallInst->getParent()),
// oldCallInst->getName());
// } else {
// newCallInst = new CallInst(newFunction, newArgumnts, oldNewBlockMap.at(oldCallInst->getParent()),
// oldCallInst->getName());
// }
oldNewValueMap.emplace(oldCallInst, newCallInst);
break;
}
case Instruction::kCondBr: {
auto oldCondBrInst = dynamic_cast<CondBrInst *>(inst);
auto oldCond = oldCondBrInst->getCondition();
Value *newCond;
newCond = oldNewValueMap.at(oldCond);
auto newCondBrInst = new CondBrInst(newCond, oldNewBlockMap.at(oldCondBrInst->getThenBlock()),
oldNewBlockMap.at(oldCondBrInst->getElseBlock()), {}, {},
oldNewBlockMap.at(oldCondBrInst->getParent()));
oldNewValueMap.emplace(oldCondBrInst, newCondBrInst);
break;
}
case Instruction::kBr: {
auto oldBrInst = dynamic_cast<UncondBrInst *>(inst);
auto newBrInst =
new UncondBrInst(oldNewBlockMap.at(oldBrInst->getBlock()), {}, oldNewBlockMap.at(oldBrInst->getParent()));
oldNewValueMap.emplace(oldBrInst, newBrInst);
break;
}
case Instruction::kReturn: {
auto oldReturnInst = dynamic_cast<ReturnInst *>(inst);
auto oldRval = oldReturnInst->getReturnValue();
Value *newRval = nullptr;
if (oldRval != nullptr) {
newRval = oldNewValueMap.at(oldRval);
}
auto newReturnInst =
new ReturnInst(newRval, oldNewBlockMap.at(oldReturnInst->getParent()), oldReturnInst->getName());
oldNewValueMap.emplace(oldReturnInst, newReturnInst);
break;
}
case Instruction::kAlloca: {
assert(false);
}
case Instruction::kLoad: {
auto oldLoadInst = dynamic_cast<LoadInst *>(inst);
auto oldPointer = oldLoadInst->getPointer();
Value *newPointer;
newPointer = oldNewValueMap.at(oldPointer);
std::vector<Value *> newIndices;
for (const auto &index : oldLoadInst->getIndices()) {
newIndices.emplace_back(oldNewValueMap.at(index->getValue()));
}
ss << oldLoadInst->getName() << suffix;
auto newLoadInst = new LoadInst(newPointer, newIndices, oldNewBlockMap.at(oldLoadInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldLoadInst, newLoadInst);
break;
}
case Instruction::kStore: {
auto oldStoreInst = dynamic_cast<StoreInst *>(inst);
auto oldPointer = oldStoreInst->getPointer();
auto oldValue = oldStoreInst->getValue();
Value *newPointer;
Value *newValue;
std::vector<Value *> newIndices;
newPointer = oldNewValueMap.at(oldPointer);
newValue = oldNewValueMap.at(oldValue);
for (const auto &index : oldStoreInst->getIndices()) {
newIndices.emplace_back(oldNewValueMap.at(index->getValue()));
}
auto newStoreInst = new StoreInst(newValue, newPointer, newIndices,
oldNewBlockMap.at(oldStoreInst->getParent()), oldStoreInst->getName());
oldNewValueMap.emplace(oldStoreInst, newStoreInst);
break;
}
case Instruction::kLa: {
auto oldLaInst = dynamic_cast<LaInst *>(inst);
auto oldPointer = oldLaInst->getPointer();
Value *newPointer;
std::vector<Value *> newIndices;
newPointer = oldNewValueMap.at(oldPointer);
for (const auto &index : oldLaInst->getIndices()) {
newIndices.emplace_back(oldNewValueMap.at(index->getValue()));
}
ss << oldLaInst->getName() << suffix;
auto newLaInst = new LaInst(newPointer, newIndices, oldNewBlockMap.at(oldLaInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldLaInst, newLaInst);
break;
}
case Instruction::kGetSubArray: {
auto oldGetSubArrayInst = dynamic_cast<GetSubArrayInst *>(inst);
auto oldFather = oldGetSubArrayInst->getFatherArray();
auto oldChild = oldGetSubArrayInst->getChildArray();
Value *newFather;
Value *newChild;
std::vector<Value *> newIndices;
newFather = oldNewValueMap.at(oldFather);
newChild = oldNewValueMap.at(oldChild);
for (const auto &index : oldGetSubArrayInst->getIndices()) {
newIndices.emplace_back(oldNewValueMap.at(index->getValue()));
}
ss << oldGetSubArrayInst->getName() << suffix;
auto newGetSubArrayInst =
new GetSubArrayInst(dynamic_cast<LVal *>(newFather), dynamic_cast<LVal *>(newChild), newIndices,
oldNewBlockMap.at(oldGetSubArrayInst->getParent()), ss.str());
ss.str("");
oldNewValueMap.emplace(oldGetSubArrayInst, newGetSubArrayInst);
break;
}
case Instruction::kMemset: {
auto oldMemsetInst = dynamic_cast<MemsetInst *>(inst);
auto oldPointer = oldMemsetInst->getPointer();
auto oldValue = oldMemsetInst->getValue();
Value *newPointer;
Value *newValue;
newPointer = oldNewValueMap.at(oldPointer);
newValue = oldNewValueMap.at(oldValue);
auto newMemsetInst = new MemsetInst(newPointer, oldMemsetInst->getBegin(), oldMemsetInst->getSize(), newValue,
oldNewBlockMap.at(oldMemsetInst->getParent()), oldMemsetInst->getName());
oldNewValueMap.emplace(oldMemsetInst, newMemsetInst);
break;
}
case Instruction::kInvalid:
case Instruction::kPhi: {
break;
}
default:
assert(false);
}
for (const auto &userUse : inst->getUses()) {
auto user = userUse->getUser();
if (!isAddedToCreate.at(user)) {
toCreate.push(user);
isAddedToCreate.at(user) = true;
}
}
}
MemsetInst *createMemsetInst(Value *pointer, Value *begin, Value *size,
Value *value, const std::string &name = "") {
auto inst = new MemsetInst(pointer, begin, size, value, block, name);
return static_cast<MemsetInst*>(insertInst(inst));
for (const auto &oldBlock : blocks) {
auto newBlock = oldNewBlockMap.at(oldBlock.get());
builder.setPosition(newBlock, newBlock->end());
for (const auto &inst : oldBlock->getInstructions()) {
builder.insertInst(dynamic_cast<Instruction *>(oldNewValueMap.at(inst.get())));
}
}
StoreInst *createStoreInst(Value *value, Value *pointer,
const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new StoreInst(value, pointer, indices, block, name);
return static_cast<StoreInst*>(insertInst(inst));
for (const auto &param : blocks.front()->getArguments()) {
newFunction->getEntryBlock()->insertArgument(dynamic_cast<AllocaInst *>(oldNewValueMap.at(param)));
}
PhiInst *createPhiInst(Type *type, Value *lhs, BasicBlock *parent,
const std::string &name = "") {
auto predNum = parent->getNumPredecessors();
std::vector<Value *> rhs(predNum, lhs);
auto inst = new PhiInst(type, lhs, rhs, lhs, parent, name);
parent->getInstructions().emplace(parent->begin(), inst);
return inst;
}
};
return newFunction;
}
/**
* @brief 设置操作数
*
* @param [in] index 所要设置的操作数的位置
* @param [in] value 所要设置成的value
* @return 无返回值
*/
void User::setOperand(unsigned index, Value *value) {
assert(index < getNumOperands());
operands[index]->setValue(value);
value->addUse(operands[index]);
}
/**
* @brief 替换操作数
*
* @param [in] index 所要替换的操作数的位置
* @param [in] value 所要替换成的value
* @return 无返回值
*/
void User::replaceOperand(unsigned index, Value *value) {
assert(index < getNumOperands());
auto &use = operands[index];
use->getValue()->removeUse(use);
use->setValue(value);
value->addUse(use);
}
} // namespace sysy
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);
}
}
/**
* @brief 获取被调用函数的指针
*
* @return 被调用函数的指针
*/
Function * CallInst::getCallee() const { return dynamic_cast<Function *>(getOperand(0)); }
/**
* @brief 获取变量指针
*
* @param [in] name 变量名字
* @return 变量指针
*/
auto SymbolTable::getVariable(const std::string &name) const -> User * {
auto node = curNode;
while (node != nullptr) {
auto iter = node->varList.find(name);
if (iter != node->varList.end()) {
return iter->second;
}
node = node->pNode;
}
return nullptr;
}
/**
* @brief 添加变量
*
* @param [in] name 变量名字
* @param [in] variable 变量指针
* @return 变量指针
*/
auto SymbolTable::addVariable(const std::string &name, User *variable) -> User * {
User *result = nullptr;
if (curNode != nullptr) {
std::stringstream ss;
auto iter = variableIndex.find(name);
if (iter != variableIndex.end()) {
ss << name << "(" << iter->second << ")";
iter->second += 1;
} else {
variableIndex.emplace(name, 1);
ss << name << "(" << 0 << ")";
}
variable->setName(ss.str());
curNode->varList.emplace(name, variable);
auto global = dynamic_cast<GlobalValue *>(variable);
auto constvar = dynamic_cast<ConstantVariable *>(variable);
if (global != nullptr) {
globals.emplace_back(global);
} else if (constvar != nullptr) {
consts.emplace_back(constvar);
}
result = variable;
}
return result;
}
/**
* @brief 获取全局变量
*
* @return 全局变量列表
*/
auto SymbolTable::getGlobals() -> std::vector<std::unique_ptr<GlobalValue>> & { return globals; }
/**
* @brief 获取常量
*
* @return 常量列表
*/
auto SymbolTable::getConsts() const -> const std::vector<std::unique_ptr<ConstantVariable>> & { return consts; }
/**
* @brief 进入新的作用域
*
* @return 无返回值
*/
void SymbolTable::enterNewScope() {
auto newNode = new SymbolTableNode;
nodeList.emplace_back(newNode);
if (curNode != nullptr) {
curNode->children.emplace_back(newNode);
}
newNode->pNode = curNode;
curNode = newNode;
}
/**
* @brief 进入全局作用域
*
* @return 无返回值
*/
void SymbolTable::enterGlobalScope() { curNode = nodeList.front().get(); }
/**
* @brief 离开作用域
*
* @return 无返回值
*/
void SymbolTable::leaveScope() { curNode = curNode->pNode; }
/**
* @brief 是否位于全局作用域
*
* @return 布尔值
*/
auto SymbolTable::isInGlobalScope() const -> bool { return curNode->pNode == nullptr; }
/**
* @brief 判断是否为循环不变量
* @param value: 要判断的value
* @return true: 是不变量
* @return false: 不是
*/
auto Loop::isSimpleLoopInvariant(Value *value) -> bool {
// auto constValue = dynamic_cast<ConstantValue *>(value);
// if (constValue != nullptr) {
// return false;
// }
if (auto instr = dynamic_cast<Instruction *>(value)) {
if (instr->isLoad()) {
auto loadinst = dynamic_cast<LoadInst *>(instr);
auto loadvalue = dynamic_cast<AllocaInst *>(loadinst->getOperand(0));
if (loadvalue != nullptr) {
if (loadvalue->getParent() != nullptr) {
auto basicblock = loadvalue->getParent();
return !this->isLoopContainsBasicBlock(basicblock);
}
}
auto globalvalue = dynamic_cast<GlobalValue *>(loadinst->getOperand(0));
if (globalvalue != nullptr) {
return true;
}
auto basicblock = instr->getParent();
return !this->isLoopContainsBasicBlock(basicblock);
}
auto basicblock = instr->getParent();
return !this->isLoopContainsBasicBlock(basicblock);
}
return true;
}
/**
* @brief 移动指令
*
* @param [in] sourcePos 源指令列表位置
* @param [in] targetPos 目的指令列表位置
* @param [in] block 目标基本块
* @return 无返回值
*/
auto BasicBlock::moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block) -> iterator {
auto inst = sourcePos->release();
inst->setParent(block);
block->instructions.emplace(targetPos, inst);
return instructions.erase(sourcePos);
}
} // namespace sysy

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,25 @@
#pragma once
#include "IR.h"
#include <cassert>
#include <memory>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include "IR.h"
/**
* @file IRBuilder.h
*
* @brief 定义IR构建器的头文件
*/
namespace sysy {
/**
* @brief 中间IR的构建器
*
*/
class IRBuilder {
private:
private:
unsigned labelIndex; ///< 基本块标签编号
unsigned tmpIndex; ///< 临时变量编号
@ -20,222 +32,325 @@ private:
std::vector<BasicBlock *> breakBlocks; ///< break目标块列表
std::vector<BasicBlock *> continueBlocks; ///< continue目标块列表
public:
public:
IRBuilder() : labelIndex(0), tmpIndex(0), block(nullptr) {}
explicit IRBuilder(BasicBlock *block) : labelIndex(0), tmpIndex(0), block(block), position(block->end()) {}
IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: labelIndex(0), tmpIndex(0), block(block), position(position) {}
public:
BasicBlock *getBasicBlock() const { return block; }
BasicBlock::iterator getPosition() const { return position; }
public:
auto getLabelIndex() -> unsigned {
labelIndex += 1;
return labelIndex - 1;
} ///< 获取基本块标签编号
auto getTmpIndex() -> unsigned {
tmpIndex += 1;
return tmpIndex - 1;
} ///< 获取临时变量编号
auto getBasicBlock() const -> BasicBlock * { return block; } ///< 获取当前基本块
auto getBreakBlock() const -> BasicBlock * { return breakBlocks.back(); } ///< 获取break目标块
auto popBreakBlock() -> BasicBlock * {
auto result = breakBlocks.back();
breakBlocks.pop_back();
return result;
} ///< 弹出break目标块
auto getContinueBlock() const -> BasicBlock * { return continueBlocks.back(); } ///< 获取continue目标块
auto popContinueBlock() -> BasicBlock * {
auto result = continueBlocks.back();
continueBlocks.pop_back();
return result;
} ///< 弹出continue目标块
auto getTrueBlock() const -> BasicBlock * { return trueBlocks.back(); } ///< 获取true分支基本块
auto getFalseBlock() const -> BasicBlock * { return falseBlocks.back(); } ///< 获取false分支基本块
auto popTrueBlock() -> BasicBlock * {
auto result = trueBlocks.back();
trueBlocks.pop_back();
return result;
} ///< 弹出true分支基本块
auto popFalseBlock() -> BasicBlock * {
auto result = falseBlocks.back();
falseBlocks.pop_back();
return result;
} ///< 弹出false分支基本块
auto getPosition() const -> BasicBlock::iterator { return position; } ///< 获取当前基本块指令列表位置的迭代器
void setPosition(BasicBlock *block, BasicBlock::iterator position) {
this->block = block;
this->position = position;
}
void setPosition(BasicBlock::iterator position) { this->position = position; }
} ///< 设置基本块和基本块指令列表位置的迭代器
void setPosition(BasicBlock::iterator position) {
this->position = position;
} ///< 设置当前基本块指令列表位置的迭代器
void pushBreakBlock(BasicBlock *block) { breakBlocks.push_back(block); } ///< 压入break目标基本块
void pushContinueBlock(BasicBlock *block) { continueBlocks.push_back(block); } ///< 压入continue目标基本块
void pushTrueBlock(BasicBlock *block) { trueBlocks.push_back(block); } ///< 压入true分支基本块
void pushFalseBlock(BasicBlock *block) { falseBlocks.push_back(block); } ///< 压入false分支基本块
public:
CallInst *createCallInst(Function *callee,
const std::vector<Value *> &args = {},
const std::string &name = "") {
auto inst = new CallInst(callee, args, block, name);
public:
auto insertInst(Instruction *inst) -> Instruction * {
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UnaryInst *createUnaryInst(Instruction::Kind kind, Type *type, Value *operand,
const std::string &name = "") {
} ///< 插入指令
auto createUnaryInst(Instruction::Kind kind, Type *type, Value *operand, const std::string &name = "")
-> UnaryInst * {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new UnaryInst(kind, type, operand, block, name);
auto inst = new UnaryInst(kind, type, operand, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UnaryInst *createNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNeg, Type::getIntType(), operand,
name);
}
UnaryInst *createNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNot, Type::getIntType(), operand,
name);
}
UnaryInst *createFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFtoI, Type::getIntType(), operand,
name);
}
UnaryInst *createFNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNeg, Type::getFloatType(), operand,
name);
}
UnaryInst *createIToFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand,
name);
}
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);
} ///< 创建一元指令
auto createNegInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kNeg, Type::getIntType(), operand, name);
} ///< 创建取反指令
auto createNotInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kNot, Type::getIntType(), operand, name);
} ///< 创建取非指令
auto createFtoIInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kFtoI, Type::getIntType(), operand, name);
} ///< 创建浮点转整型指令
auto createBitFtoIInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kBitFtoI, Type::getIntType(), operand, name);
} ///< 创建按位浮点转整型指令
auto createFNegInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kFNeg, Type::getFloatType(), operand, name);
} ///< 创建浮点取反指令
auto createFNotInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kFNot, Type::getIntType(), operand, name);
} ///< 创建浮点取非指令
auto createIToFInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand, name);
} ///< 创建整型转浮点指令
auto createBitItoFInst(Value *operand, const std::string &name = "") -> UnaryInst * {
return createUnaryInst(Instruction::kBitItoF, Type::getFloatType(), operand, name);
} ///< 创建按位整型转浮点指令
auto createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs, Value *rhs, const std::string &name = "")
-> BinaryInst * {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new BinaryInst(kind, type, lhs, rhs, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
BinaryInst *createAddInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kAdd, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createSubInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kSub, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createMulInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kMul, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createDivInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kDiv, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createRemInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kRem, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpEQInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpEQ, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpNEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpNE, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpLTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLT, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpLEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLE, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpGTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGT, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createICmpGEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGE, Type::getIntType(), lhs, rhs,
name);
}
BinaryInst *createFAddInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFAdd, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFSubInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFSub, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFMulInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFMul, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFDivInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFDiv, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFRemInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFRem, Type::getFloatType(), lhs, rhs,
name);
}
BinaryInst *createFCmpEQInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpEQ, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpNEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpNE, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpLTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLT, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpLEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLE, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpGTInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGT, Type::getFloatType(), lhs,
rhs, name);
}
BinaryInst *createFCmpGEInst(Value *lhs, Value *rhs,
const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGE, Type::getFloatType(), lhs,
rhs, name);
}
ReturnInst *createReturnInst(Value *value = nullptr) {
auto inst = new ReturnInst(value);
} ///< 创建二元指令
auto createAddInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kAdd, Type::getIntType(), lhs, rhs, name);
} ///< 创建加法指令
auto createSubInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kSub, Type::getIntType(), lhs, rhs, name);
} ///< 创建减法指令
auto createMulInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kMul, Type::getIntType(), lhs, rhs, name);
} ///< 创建乘法指令
auto createDivInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kDiv, Type::getIntType(), lhs, rhs, name);
} ///< 创建除法指令
auto createRemInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kRem, Type::getIntType(), lhs, rhs, name);
} ///< 创建取余指令
auto createICmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kICmpEQ, Type::getIntType(), lhs, rhs, name);
} ///< 创建相等设置指令
auto createICmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kICmpNE, Type::getIntType(), lhs, rhs, name);
} ///< 创建不相等设置指令
auto createICmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kICmpLT, Type::getIntType(), lhs, rhs, name);
} ///< 创建小于设置指令
auto createICmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kICmpLE, Type::getIntType(), lhs, rhs, name);
} ///< 创建小于等于设置指令
auto createICmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kICmpGT, Type::getIntType(), lhs, rhs, name);
} ///< 创建大于设置指令
auto createICmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kICmpGE, Type::getIntType(), lhs, rhs, name);
} ///< 创建大于等于设置指令
auto createFAddInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFAdd, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点加法指令
auto createFSubInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFSub, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点减法指令
auto createFMulInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFMul, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点乘法指令
auto createFDivInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFDiv, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点除法指令
auto createFCmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFCmpEQ, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点相等设置指令
auto createFCmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFCmpNE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点不相等设置指令
auto createFCmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFCmpLT, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点小于设置指令
auto createFCmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFCmpLE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点小于等于设置指令
auto createFCmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFCmpGT, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点大于设置指令
auto createFCmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kFCmpGE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点相大于等于设置指令
auto createAndInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kAnd, Type::getIntType(), lhs, rhs, name);
} ///< 创建按位且指令
auto createOrInst(Value *lhs, Value *rhs, const std::string &name = "") -> BinaryInst * {
return createBinaryInst(Instruction::kOr, Type::getIntType(), lhs, rhs, name);
} ///< 创建按位或指令
auto createCallInst(Function *callee, const std::vector<Value *> &args, const std::string &name = "") -> CallInst * {
std::string newName;
if (name.empty() && callee->getReturnType() != Type::getVoidType()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new CallInst(callee, args, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
UncondBrInst *createUncondBrInst(BasicBlock *block,
std::vector<Value *> args) {
auto inst = new UncondBrInst(block, args, block);
} ///< 创建Call指令
auto createReturnInst(Value *value = nullptr, const std::string &name = "") -> ReturnInst * {
auto inst = new ReturnInst(value, block, name);
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);
} ///< 创建return指令
auto createUncondBrInst(BasicBlock *thenBlock, const std::vector<Value *> &args) -> UncondBrInst * {
auto inst = new UncondBrInst(thenBlock, args, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
AllocaInst *createAllocaInst(Type *type,
const std::vector<Value *> &dims = {},
const std::string &name = "") {
} ///< 创建无条件指令
auto createCondBrInst(Value *condition, BasicBlock *thenBlock, BasicBlock *elseBlock,
const std::vector<Value *> &thenArgs, const std::vector<Value *> &elseArgs) -> CondBrInst * {
auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs, elseArgs, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建条件跳转指令
auto createAllocaInst(Type *type, const std::vector<Value *> &dims = {}, const std::string &name = "")
-> AllocaInst * {
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);
} ///< 创建分配指令
auto createAllocaInstWithoutInsert(Type *type, const std::vector<Value *> &dims = {}, BasicBlock *parent = nullptr,
const std::string &name = "") -> AllocaInst * {
auto inst = new AllocaInst(type, dims, parent, name);
assert(inst);
return inst;
} ///< 创建不插入指令列表的分配指令
auto createLoadInst(Value *pointer, const std::vector<Value *> &indices = {}, const std::string &name = "")
-> LoadInst * {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new LoadInst(pointer, indices, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
StoreInst *createStoreInst(Value *value, Value *pointer,
const std::vector<Value *> &indices = {},
const std::string &name = "") {
} ///< 创建load指令
auto createLaInst(Value *pointer, const std::vector<Value *> &indices = {}, const std::string &name = "")
-> LaInst * {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new LaInst(pointer, indices, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建la指令
auto createGetSubArray(LVal *fatherArray, const std::vector<Value *> &indices, const std::string &name = "")
-> GetSubArrayInst * {
assert(fatherArray->getLValNumDims() > indices.size());
std::vector<Value *> subDims;
auto dims = fatherArray->getLValDims();
auto iter = std::next(dims.begin(), indices.size());
while (iter != dims.end()) {
subDims.emplace_back(*iter);
iter++;
}
std::string childArrayName;
std::stringstream ss;
ss << "A"
<< "%" << tmpIndex;
childArrayName = ss.str();
tmpIndex++;
auto fatherArrayValue = dynamic_cast<Value *>(fatherArray);
auto childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block, childArrayName);
auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建获取部分数组指令
auto createMemsetInst(Value *pointer, Value *begin, Value *size, Value *value, const std::string &name = "")
-> MemsetInst * {
auto inst = new MemsetInst(pointer, begin, size, value, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建memset指令
auto createStoreInst(Value *value, Value *pointer, const std::vector<Value *> &indices = {},
const std::string &name = "") -> StoreInst * {
auto inst = new StoreInst(value, pointer, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
} ///< 创建store指令
auto createPhiInst(Type *type, Value *lhs, BasicBlock *parent, const std::string &name = "") -> PhiInst * {
auto predNum = parent->getNumPredecessors();
std::vector<Value *> rhs;
for (size_t i = 0; i < predNum; i++) {
rhs.push_back(lhs);
}
auto inst = new PhiInst(type, lhs, rhs, lhs, parent, name);
assert(inst);
parent->getInstructions().emplace(parent->begin(), inst);
return inst;
} ///< 创建Phi指令
};
} // namespace sysy
} // namespace sysy