From 30f89bba23defec8f53b577458af45f738fec1f9 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sat, 21 Jun 2025 12:53:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0IR=E7=BB=93=E6=9E=84=EF=BC=8C?= =?UTF-8?q?=E9=87=8D=E5=86=99IRBuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/IR.cpp | 963 +++++++++++++++++++-------- src/include/IR.h | 1368 +++++++++++++++++++++++++-------------- src/include/IRBuilder.h | 477 ++++++++------ 3 files changed, 1869 insertions(+), 939 deletions(-) diff --git a/src/IR.cpp b/src/IR.cpp index 1564415..ebd61c1 100644 --- a/src/IR.cpp +++ b/src/IR.cpp @@ -1,310 +1,719 @@ -#pragma once - #include "IR.h" +#include #include #include +#include +#include #include -#include #include +#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 trueBlocks; ///< true分支基本块列表 - std::vector falseBlocks; ///< false分支基本块列表 +auto Type::getFloatType() -> Type * { + static Type floatType(kFloat); + return &floatType; +} - std::vector breakBlocks; ///< break目标块列表 - std::vector 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 ¶mTypes) -> 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> 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 ¶mTypes) { + static std::set> functionTypes; + auto iter = + std::find_if(functionTypes.begin(), functionTypes.end(), [&](const std::unique_ptr &type) -> bool { + if (returnType != type->getReturnType() || + paramTypes.size() != static_cast(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> 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> 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 { + std::set 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 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(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 oldNewValueMap; + std::map isAddedToCreate; + std::map isCreated; + std::queue 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(value); + if (oldAllocInst != nullptr) { + std::vector 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(inst.get()); + std::vector 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(value); + auto constVariable = dynamic_cast(value); + auto constantValue = dynamic_cast(value); + auto functionValue = dynamic_cast(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(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(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(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 &args, - const std::string &name = "") { - auto inst = new CallInst(callee, args, block, name); - return static_cast(insertInst(inst)); - } - - ReturnInst *createReturnInst(Value *value = nullptr) { - auto inst = new ReturnInst(value, block); - return static_cast(insertInst(inst)); - } - - UncondBrInst *createUncondBrInst(BasicBlock *thenBlock, - const std::vector &args) { - auto inst = new UncondBrInst(thenBlock, args, block); - return static_cast(insertInst(inst)); - } - - CondBrInst *createCondBrInst(Value *condition, BasicBlock *thenBlock, - BasicBlock *elseBlock, - const std::vector &thenArgs, - const std::vector &elseArgs) { - auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs, elseArgs, block); - return static_cast(insertInst(inst)); - } - - AllocaInst *createAllocaInst(Type *type, const std::vector &dims = {}, - const std::string &name = "") { - auto inst = new AllocaInst(type, dims, block, name); - return static_cast(insertInst(inst)); - } - - AllocaInst *createAllocaInstWithoutInsert(Type *type, - const std::vector &dims = {}, - BasicBlock *parent = nullptr, - const std::string &name = "") { - return new AllocaInst(type, dims, parent, name); - } - - LoadInst *createLoadInst(Value *pointer, const std::vector &indices = {}, - const std::string &name = "") { - auto inst = new LoadInst(pointer, indices, block, name); - return static_cast(insertInst(inst)); - } - - LaInst *createLaInst(Value *pointer, const std::vector &indices = {}, - const std::string &name = "") { - auto inst = new LaInst(pointer, indices, block, name); - return static_cast(insertInst(inst)); - } - - GetSubArrayInst *createGetSubArray(LVal *fatherArray, - const std::vector &indices, - const std::string &name = "") { - assert(fatherArray->getLValNumDims() > indices.size()); - std::vector 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(valueUse->getValue()); + if (value != nullptr && !isCreated.at(value)) { + isReady = false; + break; + } } - auto fatherArrayValue = dynamic_cast(fatherArray); - AllocaInst * childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block); - auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block ,name); - return static_cast(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(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(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(inst); + std::vector 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(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(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(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(inst); + auto oldPointer = oldLoadInst->getPointer(); + Value *newPointer; + newPointer = oldNewValueMap.at(oldPointer); + + std::vector 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(inst); + auto oldPointer = oldStoreInst->getPointer(); + auto oldValue = oldStoreInst->getValue(); + Value *newPointer; + Value *newValue; + std::vector 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(inst); + auto oldPointer = oldLaInst->getPointer(); + Value *newPointer; + std::vector 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(inst); + auto oldFather = oldGetSubArrayInst->getFatherArray(); + auto oldChild = oldGetSubArrayInst->getChildArray(); + Value *newFather; + Value *newChild; + std::vector 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(newFather), dynamic_cast(newChild), newIndices, + oldNewBlockMap.at(oldGetSubArrayInst->getParent()), ss.str()); + ss.str(""); + oldNewValueMap.emplace(oldGetSubArrayInst, newGetSubArrayInst); + break; + } + + case Instruction::kMemset: { + auto oldMemsetInst = dynamic_cast(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(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(oldNewValueMap.at(inst.get()))); + } } - StoreInst *createStoreInst(Value *value, Value *pointer, - const std::vector &indices = {}, - const std::string &name = "") { - auto inst = new StoreInst(value, pointer, indices, block, name); - return static_cast(insertInst(inst)); + for (const auto ¶m : blocks.front()->getArguments()) { + newFunction->getEntryBlock()->insertArgument(dynamic_cast(oldNewValueMap.at(param))); } - PhiInst *createPhiInst(Type *type, Value *lhs, BasicBlock *parent, - const std::string &name = "") { - auto predNum = parent->getNumPredecessors(); - std::vector 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 &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(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(variable); + auto constvar = dynamic_cast(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> & { return globals; } +/** + * @brief 获取常量 + * + * @return 常量列表 + */ +auto SymbolTable::getConsts() const -> const std::vector> & { 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(value); + // if (constValue != nullptr) { + // return false; + // } + if (auto instr = dynamic_cast(value)) { + if (instr->isLoad()) { + auto loadinst = dynamic_cast(instr); + + auto loadvalue = dynamic_cast(loadinst->getOperand(0)); + if (loadvalue != nullptr) { + if (loadvalue->getParent() != nullptr) { + auto basicblock = loadvalue->getParent(); + return !this->isLoopContainsBasicBlock(basicblock); + } + } + auto globalvalue = dynamic_cast(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 diff --git a/src/include/IR.h b/src/include/IR.h index 1f3885b..f1759cd 100644 --- a/src/include/IR.h +++ b/src/include/IR.h @@ -340,41 +340,6 @@ class Function; class Loop; class BasicBlock; -/*! - * Arguments of `BasicBlock`s. - * - * SysY IR is an SSA language, however, it does not use PHI instructions as in - * LLVM IR. `Value`s from different predecessor blocks are passed explicitly as - * block arguments. This is also the approach used by MLIR. - * NOTE that `Function` does not own `Argument`s, function arguments are - * implemented as its entry block's arguments. - */ - -class Argument : public Value { -protected: - BasicBlock *block; - int index; - -public: - Argument(Type *type, BasicBlock *block, int index, - const std::string &name = ""); - -public: - static bool classof(const Value *value) { - return value->getKind() == kArgument; - } - -public: - BasicBlock *getParent() const { return block; } - int getIndex() const { return index; } - -public: - void print(std::ostream &os) const override; -}; - -class Instruction; -class Function; -class Loop; /*! * The container for `Instruction` sequence. * @@ -382,104 +347,131 @@ class Loop; * a terminator (branch or return). Besides, `BasicBlock` stores its arguments * and records its predecessor and successor `BasicBlock`s. */ -class BasicBlock : public Value { + + class BasicBlock : public Value { friend class Function; -public: + public: using inst_list = std::list>; using iterator = inst_list::iterator; - using arg_list = std::vector>; + using arg_list = std::vector; using block_list = std::vector; using block_set = std::unordered_set; -protected: - Function *parent; - inst_list instructions; - arg_list arguments; - block_list successors; - block_list predecessors; - BasicBlock *idom = nullptr; // 直接支配节点 - block_list sdoms; // 支配树后继 - block_set dominants; // 必经节点集合 - block_set dominant_frontiers; // 支配边界 - bool reachable = false; // 是否可达 - Loop *loopbelong = nullptr; // 所属循环 - int loopdepth = 0; // 循环深度 + protected: + Function *parent; ///< 从属的函数 + inst_list instructions; ///< 拥有的指令序列 + arg_list arguments; ///< 分配空间后的形式参数列表 + block_list successors; ///< 前驱列表 + block_list predecessors; ///< 后继列表 + BasicBlock *idom = nullptr; ///< 直接支配结点,即支配树前驱,唯一,默认nullptr + block_list sdoms; ///< 支配树后继,可以有多个 + block_set dominants; ///< 必经结点集合 + block_set dominant_frontiers; ///< 支配边界 + bool reachable = false; ///< 用于表示该节点是否可达,默认不可达 + Loop *loopbelong = nullptr; ///< 用来表示该块属于哪个循环,唯一,默认nullptr + int loopdepth = 0; /// < 用来表示其归属循环的深度,默认0 -protected: - explicit BasicBlock(Function *parent, const std::string &name = ""); + public: + explicit BasicBlock(Function *parent, const std::string &name = "") + : Value(Type::getLabelType(), name), parent(parent) {} -public: - static bool classof(const Value *value) { - return value->getKind() == kBasicBlock; - } + ~BasicBlock() override { + for (auto pre : predecessors) { + pre->removeSuccessor(this); + } -public: - int getNumInstructions() const { return instructions.size(); } - int getNumArguments() const { return arguments.size(); } - int getNumPredecessors() const { return predecessors.size(); } - int getNumSuccessors() const { return successors.size(); } - Function *getParent() const { return parent; } - inst_list &getInstructions() { return instructions; } - auto getArguments() const { return make_range(arguments); } - const block_list &getPredecessors() const { return predecessors; } - block_list &getPredecessors() { return predecessors; } - const block_list &getSuccessors() const { return successors; } - block_list &getSuccessors() { return successors; } - iterator begin() { return instructions.begin(); } - iterator end() { return instructions.end(); } - iterator terminator() { return std::prev(end()); } - Argument *createArgument(Type *type, const std::string &name = "") { - auto arg = new Argument(type, this, arguments.size(), name); - assert(arg); - arguments.emplace_back(arg); - return arguments.back().get(); - }; + for (auto suc : successors) { + suc->removePredecessor(this); + } + } ///< 基本块的析构函数,同时删除其前驱后继关系 - // 控制流分析相关 - BasicBlock *getIdom() const { return idom; } - void setIdom(BasicBlock *dom) { idom = dom; } - const block_list &getSdoms() const { return sdoms; } - void addSdom(BasicBlock *bb) { sdoms.push_back(bb); } + public: + auto getNumInstructions() const -> unsigned { return instructions.size(); } ///< 获取指令数量 + auto getNumArguments() const -> unsigned { return arguments.size(); } ///< 获取形式参数数量 + auto getNumPredecessors() const -> unsigned { return predecessors.size(); } ///< 获取前驱数量 + auto getNumSuccessors() const -> unsigned { return successors.size(); } ///< 获取后继数量 + auto getParent() const -> Function * { return parent; } ///< 获取父函数 + void setParent(Function *func) { parent = func; } ///< 设置父函数 + auto getInstructions() -> inst_list & { return instructions; } ///< 获取指令列表 + auto getArguments() -> arg_list & { return arguments; } ///< 获取分配空间后的形式参数列表 + auto getPredecessors() const -> const block_list & { return predecessors; } ///< 获取前驱列表 + auto getSuccessors() -> block_list & { return successors; } ///< 获取后继列表 + auto getDominants() -> block_set & { return dominants; } + auto getIdom() -> BasicBlock * { return idom; } + auto getSdoms() -> block_list & { return sdoms; } + auto getDFs() -> block_set & { return dominant_frontiers; } + auto begin() -> iterator { return instructions.begin(); } ///< 返回指向指令列表开头的迭代器 + auto end() -> iterator { return instructions.end(); } ///< 返回指向指令列表末尾的迭代器 + auto terminator() -> iterator { return std::prev(end()); } ///< 基本块最后的IR + void insertArgument(AllocaInst *inst) { arguments.push_back(inst); } ///< 插入分配空间后的形式参数 + void addPredecessor(BasicBlock *block) { + if (std::find(predecessors.begin(), predecessors.end(), block) == predecessors.end()) { + predecessors.push_back(block); + } + } ///< 添加前驱 + void addSuccessor(BasicBlock *block) { + if (std::find(successors.begin(), successors.end(), block) == successors.end()) { + successors.push_back(block); + } + } ///< 添加后继 + void addPredecessor(const block_list &blocks) { + for (auto block : blocks) { + addPredecessor(block); + } + } ///< 添加多个前驱 + void addSuccessor(const block_list &blocks) { + for (auto block : blocks) { + addSuccessor(block); + } + } ///< 添加多个后继 + void setIdom(BasicBlock *block) { idom = block; } + void addSdoms(BasicBlock *block) { sdoms.push_back(block); } void clearSdoms() { sdoms.clear(); } - const block_set &getDominants() const { return dominants; } - void addDominant(BasicBlock *bb) { dominants.insert(bb); } - void setDominants(const block_set &doms) { dominants = doms; } - const block_set &getDominantFrontiers() const { return dominant_frontiers; } - void setDominantFrontiers(const block_set &df) { dominant_frontiers = df; } - bool isReachable() const { return reachable; } - void setReachable(bool r) { reachable = r; } - - // 循环分析相关 - Loop *getLoop() const { return loopbelong; } - void setLoop(Loop *loop) { loopbelong = loop; } - int getLoopDepth() const { return loopdepth; } - void setLoopDepth(int depth) { loopdepth = depth; } - - void addPredecessor(BasicBlock *bb) { - if (std::find(predecessors.begin(), predecessors.end(), bb) == predecessors.end()) - predecessors.push_back(bb); + // 重载1,参数为 BasicBlock* + auto addDominants(BasicBlock *block) -> void { dominants.emplace(block); } + // 重载2,参数为 block_set + auto addDominants(const block_set &blocks) -> void { dominants.insert(blocks.begin(), blocks.end()); } + auto setDominants(BasicBlock *block) -> void { + dominants.clear(); + addDominants(block); } - - void addSuccessor(BasicBlock *bb) { - if (std::find(successors.begin(), successors.end(), bb) == successors.end()) - successors.push_back(bb); + auto setDominants(const block_set &doms) -> void { + dominants.clear(); + addDominants(doms); } - - void removePredecessor(BasicBlock *bb) { - auto it = std::find(predecessors.begin(), predecessors.end(), bb); - if (it != predecessors.end()) - predecessors.erase(it); + auto setDFs(const block_set &df) -> void { + dominant_frontiers.clear(); + for (auto elem : df) { + dominant_frontiers.emplace(elem); + } } - - void removeSuccessor(BasicBlock *bb) { - auto it = std::find(successors.begin(), successors.end(), bb); - if (it != successors.end()) - successors.erase(it); - } - - // 获取支配树中所有子节点 - block_list getChildren() { + void removePredecessor(BasicBlock *block) { + auto iter = std::find(predecessors.begin(), predecessors.end(), block); + if (iter != predecessors.end()) { + predecessors.erase(iter); + } else { + assert(false); + } + } ///< 删除前驱 + void removeSuccessor(BasicBlock *block) { + auto iter = std::find(successors.begin(), successors.end(), block); + if (iter != successors.end()) { + successors.erase(iter); + } else { + assert(false); + } + } ///< 删除后继 + void replacePredecessor(BasicBlock *oldBlock, BasicBlock *newBlock) { + for (auto &predecessor : predecessors) { + if (predecessor == oldBlock) { + predecessor = newBlock; + break; + } + } + } ///< 替换前驱 + // 获取支配树中该块的所有子节点,包括子节点的子节点等,迭代实现 + auto getChildren() -> block_list { std::queue q; block_list children; for (auto sdom : sdoms) { @@ -494,60 +486,73 @@ public: children.push_back(sdom); } } + return children; } -public: - void print(std::ostream &os) const override; -}; // class BasicBlock + auto setreachableTrue() -> void { reachable = true; } ///< 设置可达 + + auto setreachableFalse() -> void { reachable = false; } ///< 设置不可达 + + auto getreachable() -> bool { return reachable; } ///< 返回可达状态 + + static void conectBlocks(BasicBlock *prev, BasicBlock *next) { + prev->addSuccessor(next); + next->addPredecessor(prev); + } ///< 连接两个块,即设置两个基本块的前驱后继关系 + void setLoop(Loop *loop2set) { loopbelong = loop2set; } ///< 设置所属循环 + auto getLoop() { return loopbelong; } ///< 获得所属循环 + void setLoopDepth(int loopdepth2set) { loopdepth = loopdepth2set; } ///< 设置循环深度 + auto getLoopDepth() { return loopdepth; } ///< 获得其在循环的深度 + void removeInst(iterator pos) { instructions.erase(pos); } ///< 删除指令 + auto moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block) -> iterator; ///< 移动指令 +}; //! User is the abstract base type of `Value` types which use other `Value` as //! operands. Currently, there are two kinds of `User`s, `Instruction` and //! `GlobalValue`. +// User是`Value`的派生类型,其使用其他的`Value`作为操作数 + + class User : public Value { -protected: - std::vector operands; + protected: + std::vector> operands; ///< 操作数/使用关系 -protected: - User(Kind kind, Type *type, const std::string &name = "") - : Value(kind, type, name), operands() {} + protected: + explicit User(Type *type, const std::string &name = "") : Value(type, name) {} -public: - using use_iterator = std::vector::const_iterator; - struct operand_iterator : public std::vector::const_iterator { - using Base = std::vector::const_iterator; - operand_iterator(const Base &iter) : Base(iter) {} - using value_type = Value *; - value_type operator->() { return Base::operator*().getValue(); } - value_type operator*() { return Base::operator*().getValue(); } - }; - -public: - int getNumOperands() const { return operands.size(); } - operand_iterator operand_begin() const { return operands.begin(); } - operand_iterator operand_end() const { return operands.end(); } - auto getOperands() const { - return make_range(operand_begin(), operand_end()); - } - Value *getOperand(int index) const { return operands[index].getValue(); } + public: + auto getNumOperands() const -> unsigned { return operands.size(); } ///< 获取操作数数量 + auto operand_begin() const { return operands.begin(); } ///< 返回操作数列表的开头迭代器 + auto operand_end() const { return operands.end(); } ///< 返回操作数列表的结尾迭代器 + auto getOperands() const { return make_range(operand_begin(), operand_end()); } ///< 获取操作数列表 + auto getOperand(unsigned index) const -> Value * { return operands[index]->getValue(); } ///< 获取位置为index的操作数 void addOperand(Value *value) { - operands.emplace_back(operands.size(), this, value); - value->addUse(&operands.back()); - } - template void addOperands(const ContainerT &operands) { - for (auto value : operands) + operands.emplace_back(std::make_shared(operands.size(), this, value)); + value->addUse(operands.back()); + } ///< 增加操作数 + void removeOperand(unsigned index) { + auto value = getOperand(index); + value->removeUse(operands[index]); + operands.erase(operands.begin() + index); + } ///< 移除操作数 + template + void addOperands(const ContainerT &newoperands) { + for (auto value : newoperands) { addOperand(value); - } - void replaceOperand(int index, Value *value); - void setOperand(int index, Value *value); -}; // class User + } + } ///< 增加多个操作数 + void replaceOperand(unsigned index, Value *value); ///< 替换操作数 + void setOperand(unsigned index, Value *value); ///< 设置操作数 +}; + class GetSubArrayInst; /** * 左值 具有地址的对象 */ -class LVal : public User { +class LVal { friend class GetSubArrayInst; protected: @@ -560,8 +565,8 @@ class LVal : public User { public: virtual ~LVal() = default; - virtual auto getLValDims() const -> std::vector = 0; ///< 获取左值的维度 - virtual auto getLValNumDims() const -> unsigned = 0; ///< 获取左值的维度数量 + virtual std::vector getLValDims() const = 0; ///< 获取左值的维度 + virtual unsigned getLValNumDims() const = 0; ///< 获取左值的维度数量 public: auto getFatherLVal() const -> LVal * { return fatherLVal; } ///< 获取父左值 @@ -590,23 +595,163 @@ class LVal : public User { * Base of all concrete instruction types. */ class Instruction : public User { -public: - // 指令种类定义已移至Value::Kind + public: + /// 指令标识码 + enum Kind : uint64_t { + kInvalid = 0x0UL, + // Binary + kAdd = 0x1UL << 0, + kSub = 0x1UL << 1, + kMul = 0x1UL << 2, + kDiv = 0x1UL << 3, + kRem = 0x1UL << 4, + kICmpEQ = 0x1UL << 5, + kICmpNE = 0x1UL << 6, + kICmpLT = 0x1UL << 7, + kICmpGT = 0x1UL << 8, + kICmpLE = 0x1UL << 9, + kICmpGE = 0x1UL << 10, + kFAdd = 0x1UL << 11, + kFSub = 0x1UL << 12, + kFMul = 0x1UL << 13, + kFDiv = 0x1UL << 14, + kFCmpEQ = 0x1UL << 15, + kFCmpNE = 0x1UL << 16, + kFCmpLT = 0x1UL << 17, + kFCmpGT = 0x1UL << 18, + kFCmpLE = 0x1UL << 19, + kFCmpGE = 0x1UL << 20, + kAnd = 0x1UL << 21, + kOr = 0x1UL << 22, + // Unary + kNeg = 0x1UL << 23, + kNot = 0x1UL << 24, + kFNeg = 0x1UL << 25, + kFNot = 0x1UL << 26, + kFtoI = 0x1UL << 27, + kItoF = 0x1UL << 28, + // call + kCall = 0x1UL << 29, + // terminator + kCondBr = 0x1UL << 30, + kBr = 0x1UL << 31, + kReturn = 0x1UL << 32, + // mem op + kAlloca = 0x1UL << 33, + kLoad = 0x1UL << 34, + kStore = 0x1UL << 35, + kLa = 0x1UL << 36, + kMemset = 0x1UL << 37, + kGetSubArray = 0x1UL << 38, + // constant + kConstant = 0x1UL << 37, + // phi + kPhi = 0x1UL << 39, + kBitItoF = 0x1UL << 40, + kBitFtoI = 0x1UL << 41 + }; protected: + Kind kind; BasicBlock *parent; protected: - Instruction(Kind kind, Type *type, BasicBlock *parent = nullptr, - const std::string &name = ""); + Instruction(Kind kind, Type *type, BasicBlock *parent = nullptr, const std::string &name = "") + : User(type, name), kind(kind), parent(parent) {} public: - static bool classof(const Value *value) { - return value->getKind() >= kFirstInst and value->getKind() <= kLastInst; - } public: Kind getKind() const { return kind; } + std::string getKindString() const{ + switch (kind) { + case kInvalid: + return "Invalid"; + case kAdd: + return "Add"; + case kSub: + return "Sub"; + case kMul: + return "Mul"; + case kDiv: + return "Div"; + case kRem: + return "Rem"; + case kICmpEQ: + return "ICmpEQ"; + case kICmpNE: + return "ICmpNE"; + case kICmpLT: + return "ICmpLT"; + case kICmpGT: + return "ICmpGT"; + case kICmpLE: + return "ICmpLE"; + case kICmpGE: + return "ICmpGE"; + case kFAdd: + return "FAdd"; + case kFSub: + return "FSub"; + case kFMul: + return "FMul"; + case kFDiv: + return "FDiv"; + case kFCmpEQ: + return "FCmpEQ"; + case kFCmpNE: + return "FCmpNE"; + case kFCmpLT: + return "FCmpLT"; + case kFCmpGT: + return "FCmpGT"; + case kFCmpLE: + return "FCmpLE"; + case kFCmpGE: + return "FCmpGE"; + case kAnd: + return "And"; + case kOr: + return "Or"; + case kNeg: + return "Neg"; + case kNot: + return "Not"; + case kFNeg: + return "FNeg"; + case kFNot: + return "FNot"; + case kFtoI: + return "FtoI"; + case kItoF: + return "IToF"; + case kCall: + return "Call"; + case kCondBr: + return "CondBr"; + case kBr: + return "Br"; + case kReturn: + return "Return"; + case kAlloca: + return "Alloca"; + case kLoad: + return "Load"; + case kStore: + return "Store"; + case kLa: + return "La"; + case kMemset: + return "Memset"; + case kPhi: + return "Phi"; + case kGetSubArray: + return "GetSubArray"; + default: + return "Unknown"; + } + } ///< 根据指令标识码获取字符串 + BasicBlock *getParent() const { return parent; } Function *getFunction() const { return parent->getParent(); } void setParent(BasicBlock *bb) { parent = bb; } @@ -615,7 +760,7 @@ public: static constexpr uint64_t BinaryOpMask = (kAdd | kSub | kMul | kDiv | kRem | kAnd | kOr) | (kICmpEQ | kICmpNE | kICmpLT | kICmpGT | kICmpLE | kICmpGE) | - (kFAdd | kFSub | kFMul | kFDiv | kFRem) | + (kFAdd | kFSub | kFMul | kFDiv) | (kFCmpEQ | kFCmpNE | kFCmpLT | kFCmpGT | kFCmpLE | kFCmpGE); return kind & BinaryOpMask; } @@ -626,7 +771,7 @@ public: } bool isMemory() const { static constexpr uint64_t MemoryOpMask = - kAlloca | kLoad | kStore | kLa | kMemset | kGetSubArray; + kAlloca | kLoad | kStore; return kind & MemoryOpMask; } bool isTerminator() const { @@ -659,19 +804,67 @@ public: bool isGetSubArray() const { return kind == kGetSubArray; } bool isCall() const { return kind == kCall; } bool isReturn() const { return kind == kReturn; } + bool isDefine() const { + static constexpr uint64_t DefineOpMask = kAlloca | kStore | kPhi; + return (kind & DefineOpMask) != 0U; + } }; // class Instruction class Function; //! Function call. + +class LaInst : public Instruction { + friend class Function; + friend class IRBuilder; + + protected: + explicit LaInst(Value *pointer, const std::vector &indices = {}, BasicBlock *parent = nullptr, + const std::string &name = "") + : Instruction(Kind::kLa, pointer->getType(), parent, name) { + assert(pointer); + addOperand(pointer); + addOperands(indices); + } + + public: + auto getNumIndices() const -> unsigned { return getNumOperands() - 1; } ///< 获取索引长度 + auto getPointer() const -> Value * { return getOperand(0); } ///< 获取目标变量的Value指针 + auto getIndices() const { return make_range(std::next(operand_begin()), operand_end()); } ///< 获取索引列表 + auto getIndex(unsigned index) const -> Value * { return getOperand(index + 1); } ///< 获取位置为index的索引分量 +}; + +class PhiInst : public Instruction { + friend class IRBuilder; + friend class Function; + friend class SysySSA; + + protected: + Value *map_val; // Phi的旧值 + + PhiInst(Type *type, Value *lhs, const std::vector &rhs, Value *mval, BasicBlock *parent, + const std::string &name = "") + : Instruction(Kind::kPhi, type, parent, name) { + map_val = mval; + addOperand(lhs); + addOperands(rhs); + } + + public: + Value * getMapVal() { return map_val; } + Value * getPointer() const { return getOperand(0); } + auto getValues() { return make_range(std::next(operand_begin()), operand_end()); } + Value * getValue(unsigned index) const { return getOperand(index + 1); } +}; + + class CallInst : public Instruction { + friend class Function; friend class IRBuilder; protected: CallInst(Function *callee, const std::vector &args = {}, BasicBlock *parent = nullptr, const std::string &name = ""); -public: - static bool classof(const Value *value) { return value->getKind() == kCall; } public: Function *getCallee() const; @@ -679,12 +872,11 @@ public: return make_range(std::next(operand_begin()), operand_end()); } -public: - void print(std::ostream &os) const override; }; // class CallInst //! Unary instruction, includes '!', '-' and type conversion. class UnaryInst : public Instruction { + friend class Function; friend class IRBuilder; protected: @@ -694,74 +886,110 @@ protected: addOperand(operand); } -public: - static bool classof(const Value *value) { - return Instruction::classof(value) and - static_cast(value)->isUnary(); - } public: Value *getOperand() const { return User::getOperand(0); } -public: - void print(std::ostream &os) const override; }; // class UnaryInst //! Binary instruction, e.g., arithmatic, relation, logic, etc. class BinaryInst : public Instruction { friend class IRBuilder; + friend class Function; -protected: - BinaryInst(Kind kind, Type *type, Value *lhs, Value *rhs, BasicBlock *parent, - const std::string &name = "") + protected: + BinaryInst(Kind kind, Type *type, Value *lhs, Value *rhs, BasicBlock *parent, const std::string &name = "") : Instruction(kind, type, parent, name) { addOperand(lhs); addOperand(rhs); } -public: - static bool classof(const Value *value) { - return Instruction::classof(value) and - static_cast(value)->isBinary(); - } - public: Value *getLhs() const { return getOperand(0); } Value *getRhs() const { return getOperand(1); } - -public: - void print(std::ostream &os) const override; + template + auto eval(T lhs, T rhs) -> T { + switch (getKind()) { + case kAdd: + return lhs + rhs; + case kSub: + return lhs - rhs; + case kMul: + return lhs * rhs; + case kDiv: + return lhs / rhs; + case kRem: + if constexpr (std::is_floating_point::value) { + throw std::runtime_error("Remainder operation not supported for floating point types."); + } else { + return lhs % rhs; + } + case kICmpEQ: + return lhs == rhs; + case kICmpNE: + return lhs != rhs; + case kICmpLT: + return lhs < rhs; + case kICmpGT: + return lhs > rhs; + case kICmpLE: + return lhs <= rhs; + case kICmpGE: + return lhs >= rhs; + case kFAdd: + return lhs + rhs; + case kFSub: + return lhs - rhs; + case kFMul: + return lhs * rhs; + case kFDiv: + return lhs / rhs; + case kFCmpEQ: + return lhs == rhs; + case kFCmpNE: + return lhs != rhs; + case kFCmpLT: + return lhs < rhs; + case kFCmpGT: + return lhs > rhs; + case kFCmpLE: + return lhs <= rhs; + case kFCmpGE: + return lhs >= rhs; + case kAnd: + return lhs && rhs; + case kOr: + return lhs || rhs; + default: + assert(false); + } + } ///< 根据指令类型进行二元计算,eval template模板实现 }; // class BinaryInst //! The return statement class ReturnInst : public Instruction { friend class IRBuilder; + friend class Function; -protected: - ReturnInst(Value *value = nullptr, BasicBlock *parent = nullptr) - : Instruction(kReturn, Type::getVoidType(), parent, "") { - if (value) + protected: + explicit ReturnInst(Value *value = nullptr, BasicBlock *parent = nullptr, const std::string &name = "") + : Instruction(kReturn, Type::getVoidType(), parent, name) { + if (value != nullptr) { addOperand(value); + } } -public: - static bool classof(const Value *value) { - return value->getKind() == kReturn; - } - -public: + public: bool hasReturnValue() const { return not operands.empty(); } Value *getReturnValue() const { return hasReturnValue() ? getOperand(0) : nullptr; } - -public: - void print(std::ostream &os) const override; -}; // class ReturnInst +}; //! Unconditional branch class UncondBrInst : public Instruction { friend class IRBuilder; + friend class Function; protected: UncondBrInst(BasicBlock *block, std::vector args, @@ -772,23 +1000,19 @@ protected: addOperands(args); } -public: - static bool classof(const Value *value) { return value->getKind() == kBr; } - public: BasicBlock *getBlock() const { return dyncast(getOperand(0)); } auto getArguments() const { return make_range(std::next(operand_begin()), operand_end()); } -public: - void print(std::ostream &os) const override; }; // class UncondBrInst //! Conditional branch class CondBrInst : public Instruction { friend class IRBuilder; - + friend class Function; + protected: CondBrInst(Value *condition, BasicBlock *thenBlock, BasicBlock *elseBlock, const std::vector &thenArgs, @@ -802,12 +1026,6 @@ protected: addOperands(thenArgs); addOperands(elseArgs); } - -public: - static bool classof(const Value *value) { - return value->getKind() == kCondBr; - } - public: Value *getCondition() const { return getOperand(0); } BasicBlock *getThenBlock() const { @@ -828,14 +1046,12 @@ public: return make_range(begin, end); } -public: - void print(std::ostream &os) const override; }; // class CondBrInst //! Allocate memory for stack variables, used for non-global variable declartion -class AllocaInst : public Instruction { +class AllocaInst : public Instruction , public LVal { friend class IRBuilder; - + friend class Function; protected: AllocaInst(Type *type, const std::vector &dims = {}, BasicBlock *parent = nullptr, const std::string &name = "") @@ -844,22 +1060,59 @@ protected: } public: - static bool classof(const Value *value) { - return value->getKind() == kAlloca; - } - -public: + std::vector getLValDims() const override { + std::vector dims; + for (const auto &dim : getOperands()) { + dims.emplace_back(dim->getValue()); + } + return dims; + } ///< 获取作为左值的维度数组 + unsigned getLValNumDims() const override { return getNumOperands(); } + int getNumDims() const { return getNumOperands(); } auto getDims() const { return getOperands(); } Value *getDim(int index) { return getOperand(index); } -public: - void print(std::ostream &os) const override; }; // class AllocaInst + +class GetSubArrayInst : public Instruction { + friend class IRBuilder; + friend class Function; + + public: + GetSubArrayInst(LVal *fatherArray, LVal *childArray, const std::vector &indices, + BasicBlock *parent = nullptr, const std::string &name = "") + : Instruction(Kind::kGetSubArray, Type::getVoidType(), parent, name) { + auto predicate = [childArray](const std::unique_ptr &child) -> bool { return child.get() == childArray; }; + if (std::find_if(fatherArray->childrenLVals.begin(), fatherArray->childrenLVals.end(), predicate) == + fatherArray->childrenLVals.end()) { + fatherArray->childrenLVals.emplace_back(childArray); + } + childArray->fatherLVal = fatherArray; + childArray->defineInst = this; + auto fatherArrayValue = dynamic_cast(fatherArray); + auto childArrayValue = dynamic_cast(childArray); + assert(fatherArrayValue); + assert(childArrayValue); + addOperand(fatherArrayValue); + addOperand(childArrayValue); + addOperands(indices); + } + + public: + auto getFatherArray() const -> Value * { return getOperand(0); } ///< 获取父数组 + auto getChildArray() const -> Value * { return getOperand(1); } ///< 获取子数组 + auto getFatherLVal() const -> LVal * { return dynamic_cast(getOperand(0)); } ///< 获取父左值 + auto getChildLVal() const -> LVal * { return dynamic_cast(getOperand(1)); } ///< 获取子左值 + auto getIndices() const { return make_range(std::next(operand_begin(), 2), operand_end()); } ///< 获取索引 + auto getNumIndices() const -> unsigned { return getNumOperands() - 2; } ///< 获取索引数量 +}; + //! Load a value from memory address specified by a pointer value class LoadInst : public Instruction { friend class IRBuilder; + friend class Function; protected: LoadInst(Value *pointer, const std::vector &indices = {}, @@ -870,9 +1123,6 @@ protected: addOperands(indices); } -public: - static bool classof(const Value *value) { return value->getKind() == kLoad; } - public: int getNumIndices() const { return getNumOperands() - 1; } Value *getPointer() const { return getOperand(0); } @@ -880,14 +1130,28 @@ public: return make_range(std::next(operand_begin()), operand_end()); } Value *getIndex(int index) const { return getOperand(index + 1); } + std::list getAncestorIndices() const { + std::list indices; + for (const auto &index : getIndices()) { + indices.emplace_back(index->getValue()); + } + auto curPointer = dynamic_cast(getPointer()); + while (curPointer->getFatherLVal() != nullptr) { + auto inserter = std::next(indices.begin()); + for (const auto &index : curPointer->getDefineInst()->getIndices()) { + indices.insert(inserter, index->getValue()); + } + curPointer = curPointer->getFatherLVal(); + } -public: - void print(std::ostream &os) const override; + return indices; + } ///< 获取相对于祖先数组的索引列表 }; // class LoadInst //! Store a value to memory address specified by a pointer value class StoreInst : public Instruction { friend class IRBuilder; + friend class Function; protected: StoreInst(Value *value, Value *pointer, @@ -898,9 +1162,6 @@ protected: addOperand(pointer); addOperands(indices); } - -public: - static bool classof(const Value *value) { return value->getKind() == kStore; } public: int getNumIndices() const { return getNumOperands() - 2; } @@ -910,42 +1171,29 @@ public: return make_range(std::next(operand_begin(), 2), operand_end()); } Value *getIndex(int index) const { return getOperand(index + 2); } + std::list getAncestorIndices() const { + std::list indices; + for (const auto &index : getIndices()) { + indices.emplace_back(index->getValue()); + } + auto curPointer = dynamic_cast(getPointer()); + while (curPointer->getFatherLVal() != nullptr) { + auto inserter = std::next(indices.begin()); + for (const auto &index : curPointer->getDefineInst()->getIndices()) { + indices.insert(inserter, index->getValue()); + } + curPointer = curPointer->getFatherLVal(); + } + + return indices; + } ///< 获取相对于祖先数组的索引列表 -public: - void print(std::ostream &os) const override; }; // class StoreInst -//! Get address instruction -class LaInst : public Instruction { - friend class IRBuilder; - -protected: - LaInst(Value *pointer, const std::vector &indices = {}, - BasicBlock *parent = nullptr, const std::string &name = "") - : Instruction(kLa, pointer->getType(), parent, name) { - assert(pointer); - addOperand(pointer); - addOperands(indices); - } - -public: - static bool classof(const Value *value) { return value->getKind() == kLa; } - -public: - int getNumIndices() const { return getNumOperands() - 1; } - Value *getPointer() const { return getOperand(0); } - auto getIndices() const { - return make_range(std::next(operand_begin()), operand_end()); - } - Value *getIndex(int index) const { return getOperand(index + 1); } - -public: - void print(std::ostream &os) const override; -}; - //! Memset instruction class MemsetInst : public Instruction { friend class IRBuilder; + friend class Function; protected: MemsetInst(Value *pointer, Value *begin, Value *size, Value *value, @@ -957,80 +1205,15 @@ protected: addOperand(value); } -public: - static bool classof(const Value *value) { return value->getKind() == kMemset; } - public: Value *getPointer() const { return getOperand(0); } Value *getBegin() const { return getOperand(1); } Value *getSize() const { return getOperand(2); } Value *getValue() const { return getOperand(3); } -public: - void print(std::ostream &os) const override; -}; - -//! Get subarray instruction -class GetSubArrayInst : public Instruction { - friend class IRBuilder; - -protected: - GetSubArrayInst(Value *fatherArray, Value *childArray, - const std::vector &indices, - BasicBlock *parent = nullptr, const std::string &name = "") - : Instruction(kGetSubArray, Type::getVoidType(), parent, name) { - addOperand(fatherArray); - addOperand(childArray); - addOperands(indices); - } - -public: - static bool classof(const Value *value) { - return value->getKind() == kGetSubArray; - } - -public: - Value *getFatherArray() const { return getOperand(0); } - Value *getChildArray() const { return getOperand(1); } - int getNumIndices() const { return getNumOperands() - 2; } - auto getIndices() const { - return make_range(std::next(operand_begin(), 2), operand_end()); - } - Value *getIndex(int index) const { return getOperand(index + 2); } - -public: - void print(std::ostream &os) const override; -}; - -//! Phi instruction for SSA form -class PhiInst : public Instruction { - friend class IRBuilder; - -protected: - Value *map_val; // 旧的映射关系 - - PhiInst(Type *type, Value *lhs, const std::vector &rhs, - Value *mval, BasicBlock *parent, const std::string &name = "") - : Instruction(kPhi, type, parent, name), map_val(mval) { - addOperand(lhs); - addOperands(rhs); - } - -public: - static bool classof(const Value *value) { return value->getKind() == kPhi; } - -public: - Value *getMapVal() const { return map_val; } - Value *getPointer() const { return getOperand(0); } - auto getValues() const { - return make_range(std::next(operand_begin()), operand_end()); - } - Value *getValue(unsigned index) const { return getOperand(index + 1); } - -public: - void print(std::ostream &os) const override; }; +// 循环类 class Loop { public: using block_list = std::vector; @@ -1057,7 +1240,9 @@ protected: ConstantValue *indBegin = nullptr; // 循环起始值 ConstantValue *indStep = nullptr; // 循环步长 - + + std::set GlobalValuechange; // 循环内改变的全局变量 + int StepType = 0; // 循环步长类型 bool parallelable = false; // 是否可并行 @@ -1072,7 +1257,14 @@ public: loopCount = loopCount + 1; loopID = loopCount; } - + auto getindBegin() { return indBegin; } ///< 获得循环开始值 + auto getindStep() { return indStep; } ///< 获得循环步长 + auto setindBegin(ConstantValue *indBegin2set) { indBegin = indBegin2set; } ///< 设置循环开始值 + auto setindStep(ConstantValue *indStep2set) { indStep = indStep2set; } ///< 设置循环步长 + auto setStepType(int StepType2Set) { StepType = StepType2Set; } ///< 设置循环变量规则 + auto getStepType() { return StepType; } ///< 获得循环变量规则 + auto getLoopID() -> size_t { return loopID; } + BasicBlock *getHeader() const { return headerBlock; } BasicBlock *getPreheaderBlock() const { return preheaderBlock; } block_list &getLatchBlocks() { return latchBlock; } @@ -1087,9 +1279,9 @@ public: Loop_list &getSubLoops() { return subLoops; } unsigned getLoopDepth() const { return loopDepth; } - bool contains(BasicBlock *bb) const { + bool isLoopContainsBasicBlock(BasicBlock *bb) const { return std::find(blocksInLoop.begin(), blocksInLoop.end(), bb) != blocksInLoop.end(); - } + } ///< 判断输入块是否在该循环内 void addExitingBlock(BasicBlock *bb) { exitingBlocks.insert(bb); } void addExitBlock(BasicBlock *bb) { exitBlocks.insert(bb); } @@ -1100,12 +1292,21 @@ public: void setIcmpKind(Instruction::Kind kind) { IcmpKind = kind; } Instruction::Kind getIcmpKind() const { return IcmpKind; } + bool isSimpleLoopInvariant(Value *value) ; ///< 判断是否为简单循环不变量,若其在loop中,则不是。 + void setIndEnd(Value *value) { indEnd = value; } void setIndPhi(AllocaInst *phi) { IndPhi = phi; } Value *getIndEnd() const { return indEnd; } AllocaInst *getIndPhi() const { return IndPhi; } Instruction *getIndCondVar() const { return indCondVar; } + auto addGlobalValuechange(GlobalValue *globalvaluechange2add) { + GlobalValuechange.insert(globalvaluechange2add); + } ///<添加在循环中改变的全局变量 + auto getGlobalValuechange() -> std::set & { + return GlobalValuechange; + } ///<获得在循环中改变的所有全局变量 + void setParallelable(bool flag) { parallelable = flag; } bool isParallelable() const { return parallelable; } }; @@ -1116,204 +1317,409 @@ class Function : public Value { friend class Module; protected: - Function(Module *parent, Type *type, const std::string &name) - : Value(kFunction, type, name), parent(parent), variableID(0), blockID(0), blocks() { - blocks.emplace_back(new BasicBlock(this, "entry")); - } - -public: - static bool classof(const Value *value) { - return value->getKind() == kFunction; + Function(Module *parent, Type *type, const std::string &name) : Value(type, name), parent(parent) { + blocks.emplace_back(new BasicBlock(this)); } public: using block_list = std::list>; using Loop_list = std::list>; + // 函数优化属性标识符 + enum FunctionAttribute : uint64_t { + PlaceHolder = 0x0UL, + Pure = 0x1UL << 0, + SelfRecursive = 0x1UL << 1, + SideEffect = 0x1UL << 2, + NoPureCauseMemRead = 0x1UL << 3 + }; + protected: - Module *parent; - int variableID; - int blockID; - block_list blocks; - /*是放在module中还是新建分析器呢?*/ - Loop_list loops; // 循环列表 - Loop_list topLoops; // 顶层循环 - std::unordered_map basicblock2Loop; // 基本块到循环的映射 + Module *parent; ///< 函数的父模块 + block_list blocks; ///< 函数包含的基本块列表 + Loop_list loops; ///< 函数包含的循环列表 + Loop_list topLoops; ///< 函数所包含的顶层循环; + std::list> indirectAllocas; ///< 函数中mem2reg引入的间接分配的内存 - // 数据流分析相关 - std::unordered_map value2AllocBlocks; - std::unordered_map> value2DefBlocks; - std::unordered_map> value2UseBlocks; + FunctionAttribute attribute = PlaceHolder; ///< 函数属性 + std::set callees; ///< 函数调用的函数集合 -public: - Type *getReturnType() const { - return getType()->as()->getReturnType(); + std::unordered_map basicblock2Loop; + std::unordered_map value2AllocBlocks; ///< value -- alloc block mapping + std::unordered_map> + value2DefBlocks; //< value -- define blocks mapping + std::unordered_map> value2UseBlocks; //< value -- use blocks mapping + + public: + static auto getcloneIndex() -> unsigned { + static unsigned cloneIndex = 0; + cloneIndex += 1; + return cloneIndex - 1; } - auto getParamTypes() const { - return getType()->as()->getParamTypes(); - } - auto getBasicBlocks() const { return make_range(blocks); } - BasicBlock *getEntryBlock() const { return blocks.front().get(); } - BasicBlock *addBasicBlock(const std::string &name = "") { + auto clone(const std::string &suffix = "_" + std::to_string(getcloneIndex()) + "@") const + -> Function *; ///< 复制函数 + auto getCallees() -> const std::set & { return callees; } + auto addCallee(Function *callee) -> void { callees.insert(callee); } + auto removeCallee(Function *callee) -> void { callees.erase(callee); } + auto clearCallees() -> void { callees.clear(); } + auto getCalleesWithNoExternalAndSelf() -> std::set; + auto getAttribute() const -> FunctionAttribute { return attribute; } ///< 获取函数属性 + auto setAttribute(FunctionAttribute attr) -> void { + attribute = static_cast(attribute | attr); + } ///< 设置函数属性 + auto clearAttribute() -> void { attribute = PlaceHolder; } ///< 清楚所有函数属性,只保留PlaceHolder + auto getLoopOfBasicBlock(BasicBlock *bb) -> Loop * { + return basicblock2Loop.count(bb) != 0 ? basicblock2Loop[bb] : nullptr; + } ///< 获得块所在循环 + auto getLoopDepthByBlock(BasicBlock *basicblock2Check) { + if (getLoopOfBasicBlock(basicblock2Check) != nullptr) { + auto loop = getLoopOfBasicBlock(basicblock2Check); + return loop->getLoopDepth(); + } + return static_cast(0); + } ///< 通过块,获得其所在循环深度 + auto addBBToLoop(BasicBlock *bb, Loop *LoopToadd) { basicblock2Loop[bb] = LoopToadd; } ///< 添加块与循环的映射 + auto getBBToLoopRef() -> std::unordered_map & { + return basicblock2Loop; + } ///< 获得块-循环映射表 + // auto getNewLoopPtr(BasicBlock *header) -> Loop * { return new Loop(header); } + auto getReturnType() const -> Type * { return getType()->as()->getReturnType(); } ///< 获取返回值类型 + auto getParamTypes() const { return getType()->as()->getParamTypes(); } ///< 获取形式参数类型列表 + auto getBasicBlocks() { return make_range(blocks); } ///< 获取基本块列表 + auto getBasicBlocks_NoRange() -> block_list & { return blocks; } + auto getEntryBlock() -> BasicBlock * { return blocks.front().get(); } ///< 获取入口块 + auto removeBasicBlock(BasicBlock *blockToRemove) { + auto is_same_ptr = [blockToRemove](const std::unique_ptr &ptr) { return ptr.get() == blockToRemove; }; + blocks.remove_if(is_same_ptr); + // blocks.erase(std::remove_if(blocks.begin(), blocks.end(), is_same_ptr), blocks.end()); + } ///< 将该块从function的blocks中删除 + // auto getBasicBlocks_NoRange() -> block_list & { return blocks; } + auto addBasicBlock(const std::string &name = "") -> BasicBlock * { blocks.emplace_back(new BasicBlock(this, name)); return blocks.back().get(); - } - void removeBasicBlock(BasicBlock *block) { - blocks.remove_if([&](std::unique_ptr &b) -> bool { - return block == b.get(); - }); - } - int allocateVariableID() { return variableID++; } - int allocateblockID() { return blockID++; } - - // 循环分析 - void addLoop(Loop *loop) { loops.emplace_back(loop); } - void addTopLoop(Loop *loop) { topLoops.emplace_back(loop); } - Loop_list &getLoops() { return loops; } - Loop_list &getTopLoops() { return topLoops; } - Loop *getLoopOfBasicBlock(BasicBlock *bb) { - return basicblock2Loop.count(bb) ? basicblock2Loop[bb] : nullptr; - } - void addBBToLoop(BasicBlock *bb, Loop *loop) { basicblock2Loop[bb] = loop; } - - // 数据流分析 - void addValue2AllocBlocks(Value *value, BasicBlock *block) { + } ///< 添加新的基本块 + auto addBasicBlock(BasicBlock *block) -> BasicBlock * { + blocks.emplace_back(block); + return block; + } ///< 添加基本块到blocks中 + auto addBasicBlockFront(BasicBlock *block) -> BasicBlock * { + blocks.emplace_front(block); + return block; + } // 从前端插入新的基本块 + /** value -- alloc blocks mapping */ + auto addValue2AllocBlocks(Value *value, BasicBlock *block) -> void { value2AllocBlocks[value] = block; - } - BasicBlock *getAllocBlockByValue(Value *value) { - return value2AllocBlocks.count(value) ? value2AllocBlocks[value] : nullptr; - } - void addValue2DefBlocks(Value *value, BasicBlock *block) { + } ///< 添加value -- alloc block mapping + auto getAllocBlockByValue(Value *value) -> BasicBlock * { + if (value2AllocBlocks.count(value) > 0) { + return value2AllocBlocks[value]; + } + return nullptr; + } ///< 通过value获取alloc block + auto getValue2AllocBlocks() -> std::unordered_map & { + return value2AllocBlocks; + } ///< 获取所有value -- alloc block mappings + auto removeValue2AllocBlock(Value *value) -> void { + value2AllocBlocks.erase(value); + } ///< 删除value -- alloc block mapping + /** value -- define blocks mapping */ + auto addValue2DefBlocks(Value *value, BasicBlock *block) -> void { ++value2DefBlocks[value][block]; - } - void addValue2UseBlocks(Value *value, BasicBlock *block) { + } ///< 添加value -- define block mapping + // keep in mind that the return is not a reference. + auto getDefBlocksByValue(Value *value) -> std::unordered_set { + std::unordered_set blocks; + if (value2DefBlocks.count(value) > 0) { + for (const auto &pair : value2DefBlocks[value]) { + blocks.insert(pair.first); + } + } + return blocks; + } ///< 通过value获取define blocks + auto getValue2DefBlocks() -> std::unordered_map> & { + return value2DefBlocks; + } ///< 获取所有value -- define blocks mappings + auto removeValue2DefBlock(Value *value, BasicBlock *block) -> bool { + bool changed = false; + if (--value2DefBlocks[value][block] == 0) { + value2DefBlocks[value].erase(block); + if (value2DefBlocks[value].empty()) { + value2DefBlocks.erase(value); + changed = true; + } + } + return changed; + } ///< 删除value -- define block mapping + auto getValuesOfDefBlock() -> std::unordered_set { + std::unordered_set values; + for (const auto &pair : value2DefBlocks) { + values.insert(pair.first); + } + return values; + } ///< 获取所有定义过的value + /** value -- use blocks mapping */ + auto addValue2UseBlocks(Value *value, BasicBlock *block) -> void { ++value2UseBlocks[value][block]; - } + } ///< 添加value -- use block mapping + // keep in mind that the return is not a reference. + auto getUseBlocksByValue(Value *value) -> std::unordered_set { + std::unordered_set blocks; + if (value2UseBlocks.count(value) > 0) { + for (const auto &pair : value2UseBlocks[value]) { + blocks.insert(pair.first); + } + } + return blocks; + } ///< 通过value获取use blocks + auto getValue2UseBlocks() -> std::unordered_map> & { + return value2UseBlocks; + } ///< 获取所有value -- use blocks mappings + auto removeValue2UseBlock(Value *value, BasicBlock *block) -> bool { + bool changed = false; + if (--value2UseBlocks[value][block] == 0) { + value2UseBlocks[value].erase(block); + if (value2UseBlocks[value].empty()) { + value2UseBlocks.erase(value); + changed = true; + } + } + return changed; + } ///< 删除value -- use block mapping + auto addIndirectAlloca(AllocaInst *alloca) { indirectAllocas.emplace_back(alloca); } ///< 添加间接分配 + auto getIndirectAllocas() -> std::list> & { + return indirectAllocas; + } ///< 获取间接分配列表 + + /** loop -- begin */ + + void addLoop(Loop *loop) { loops.emplace_back(loop); } ///< 添加循环(非顶层) + void addTopLoop(Loop *loop) { topLoops.emplace_back(loop); } ///< 添加顶层循环 + auto getLoops() -> Loop_list & { return loops; } ///< 获得循环(非顶层) + auto getTopLoops() -> Loop_list & { return topLoops; } ///< 获得顶层循环 + /** loop -- end */ -public: - void print(std::ostream &os) const override; }; // class Function //! Global value declared at file scope -class GlobalValue : public User { +class GlobalValue : public User, public LVal { friend class Module; protected: - Module *parent; - std::vector initValues; // 初始值列表 - bool isConst; + Module *parent; ///< 父模块 + unsigned numDims; ///< 维度数量 + ValueCounter initValues; ///< 初值 protected: GlobalValue(Module *parent, Type *type, const std::string &name, const std::vector &dims = {}, - const std::vector &initValues = {}, - bool isConst = false) - : User(kGlobal, type, name), parent(parent), - initValues(initValues), isConst(isConst) { + ValueCounter init = {}) + : User(type, name), parent(parent) { assert(type->isPointer()); addOperands(dims); + numDims = dims.size(); + if (init.size() == 0) { + unsigned num = 1; + for (unsigned i = 0; i < numDims; i++) { + num *= dynamic_cast(dims[i])->getInt(); + } + if (dynamic_cast(type)->getBaseType() == Type::getFloatType()) { + init.push_back(ConstantValue::get(0.0F), num); + } else { + init.push_back(ConstantValue::get(0), num); + } + } + initValues = init; + } + +public: + unsigned getLValNumDims() const override { return numDims; } ///< 获取作为左值的维度数量 + std::vector getLValDims() const override { + std::vector dims; + for (const auto &dim : getOperands()) { + dims.emplace_back(dim->getValue()); + } + + return dims; + } ///< 获取作为左值的维度列表 + + unsigned getNumDims() const { return numDims; } ///< 获取维度数量 + Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度 + auto getDims() const { return getOperands(); } ///< 获取维度列表 + Value* getByIndex(unsigned index) const { + return initValues.getValue(index); + } ///< 通过一维偏移量index获取初始值 + Value * getByIndices(const std::vector &indices) const { + int index = 0; + for (size_t i = 0; i < indices.size(); i++) { + index = dynamic_cast(getDim(i))->getInt() * index + + dynamic_cast(indices[i])->getInt(); + } + return getByIndex(index); + } ///< 通过多维索引indices获取初始值 + const ValueCounter &getInitValues() const { return initValues; } +}; // class GlobalValue + + +class ConstantVariable : public User, public LVal { + friend class Module; + + protected: + Module *parent; ///< 父模块 + unsigned numDims; ///< 维度数量 + ValueCounter initValues; ///< 值 + + protected: + ConstantVariable(Module *parent, Type *type, const std::string &name, const ValueCounter &init, + const std::vector &dims = {}) + : User(type, name), parent(parent) { + assert(type->isPointer()); + numDims = dims.size(); + initValues = init; + addOperands(dims); } -public: - static bool classof(const Value *value) { - return value->getKind() == kGlobal; - } + public: + unsigned getLValNumDims() const override { return numDims; } ///< 获取作为左值的维度数量 + std::vector getLValDims() const override { + std::vector dims; + for (const auto &dim : getOperands()) { + dims.emplace_back(dim->getValue()); + } -public: - const std::vector& getInitValues() const { return initValues; } - int getNumDims() const { return getNumOperands(); } - Value *getDim(int index) { return getOperand(index); } - bool isConstant() const { return isConst; } + return dims; + } ///< 获取作为左值的维度列表 + Value* getByIndex(unsigned index) const { return initValues.getValue(index); } ///< 通过一维位置index获取值 + Value* getByIndices(const std::vector &indices) const { + int index = 0; + for (size_t i = 0; i < indices.size(); i++) { + index = dynamic_cast(getDim(i))->getInt() * index + + dynamic_cast(indices[i])->getInt(); + } -public: - void print(std::ostream &os) const override{}; -}; // class GlobalValue + return getByIndex(index); + } ///< 通过多维索引indices获取初始值 + unsigned getNumDims() const { return numDims; } ///< 获取维度数量 + Value* getDim(unsigned index) const { return getOperand(index); } ///< 获取位置为index的维度 + auto getDims() const { return getOperands(); } ///< 获取维度列表 + const ValueCounter& getInitValues() const { return initValues; } ///< 获取初始值 +}; + +using SymbolTableNode = struct SymbolTableNode { + struct SymbolTableNode *pNode; ///< 父节点 + std::vector children; ///< 子节点列表 + std::map varList; ///< 变量列表 +}; + + +class SymbolTable { + private: + SymbolTableNode *curNode{}; ///< 当前所在的作用域(符号表节点) + std::map variableIndex; ///< 变量命名索引表 + std::vector> globals; ///< 全局变量列表 + std::vector> consts; ///< 常量列表 + std::vector> nodeList; ///< 符号表节点列表 + + public: + SymbolTable() = default; + + auto getVariable(const std::string &name) const -> User *; ///< 根据名字name以及当前作用域获取变量 + auto addVariable(const std::string &name, User *variable) -> User *; ///< 添加变量 + auto getGlobals() -> std::vector> &; ///< 获取全局变量列表 + auto getConsts() const -> const std::vector> &; ///< 获取常量列表 + void enterNewScope(); ///< 进入新的作用域 + void leaveScope(); ///< 离开作用域 + auto isInGlobalScope() const -> bool; ///< 是否位于全局作用域 + void enterGlobalScope(); ///< 进入全局作用域 + auto isCurNodeNull() -> bool { return curNode == nullptr; } +}; //! IR unit for representing a SysY compile unit class Module { -protected: - std::vector> children; - std::map functions; - std::map globals; - std::map externalFunctions; // 外部函数声明 + protected: + std::map> externalFunctions; ///< 外部函数表 + std::map> functions; ///< 函数表 + SymbolTable variableTable; ///< 符号表 -public: + public: Module() = default; -public: - Function *createFunction(const std::string &name, Type *type) { - if (functions.count(name)) + public: + auto createFunction(const std::string &name, Type *type) -> Function * { + auto result = functions.try_emplace(name, new Function(this, type, name)); + if (!result.second) { return nullptr; - auto func = new Function(this, type, name); - assert(func); - children.emplace_back(func); - functions.emplace(name, func); - return func; - }; - - Function *createExternalFunction(const std::string &name, Type *type) { - if (externalFunctions.count(name)) + } + return result.first->second.get(); + } ///< 创建函数 + auto createExternalFunction(const std::string &name, Type *type) -> Function * { + auto result = externalFunctions.try_emplace(name, new Function(this, type, name)); + if (!result.second) { return nullptr; - auto func = new Function(this, type, name); - assert(func); - children.emplace_back(func); - externalFunctions.emplace(name, func); - return func; - } - - GlobalValue *createGlobalValue(const std::string &name, Type *type, - const std::vector &dims = {}, - const std::vector &initValues = {}, - bool isConst = false) { - if (globals.count(name)) + } + return result.first->second.get(); + } ///< 创建外部函数 + auto createGlobalValue(const std::string &name, Type *type, const std::vector &dims = {}, + const ValueCounter &init = {}) -> GlobalValue * { + bool isFinished = variableTable.isCurNodeNull(); + if (isFinished) { + variableTable.enterGlobalScope(); + } + auto result = variableTable.addVariable(name, new GlobalValue(this, type, name, dims, init)); + if (isFinished) { + variableTable.leaveScope(); + } + if (result == nullptr) { return nullptr; - auto global = new GlobalValue(this, type, name, dims, initValues, isConst); - assert(global); - children.emplace_back(global); - globals.emplace(name, global); - return global; - } - - Function *getFunction(const std::string &name) const { + } + return dynamic_cast(result); + } ///< 创建全局变量 + auto createConstVar(const std::string &name, Type *type, const ValueCounter &init, + const std::vector &dims = {}) -> ConstantVariable * { + auto result = variableTable.addVariable(name, new ConstantVariable(this, type, name, init, dims)); + if (result == nullptr) { + return nullptr; + } + return dynamic_cast(result); + } ///< 创建常量 + void addVariable(const std::string &name, AllocaInst *variable) { + variableTable.addVariable(name, variable); + } ///< 添加变量 + auto getVariable(const std::string &name) -> User * { + return variableTable.getVariable(name); + } ///< 根据名字name和当前作用域获取变量 + auto getFunction(const std::string &name) const -> Function * { auto result = functions.find(name); - if (result == functions.end()) + if (result == functions.end()) { return nullptr; - return result->second; - } - - Function *getExternalFunction(const std::string &name) const { + } + return result->second.get(); + } ///< 获取函数 + auto getExternalFunction(const std::string &name) const -> Function * { auto result = externalFunctions.find(name); - if (result == externalFunctions.end()) + if (result == functions.end()) { return nullptr; - return result->second; - } - - GlobalValue *getGlobalValue(const std::string &name) const { - auto result = globals.find(name); - if (result == globals.end()) - return nullptr; - return result->second; - } + } + return result->second.get(); + } ///< 获取外部函数 + auto getFunctions() -> std::map> & { return functions; } ///< 获取函数列表 + auto getExternalFunctions() const -> const std::map> & { + return externalFunctions; + } ///< 获取外部函数列表 + auto getGlobals() -> std::vector> & { + return variableTable.getGlobals(); + } ///< 获取全局变量列表 + auto getConsts() const -> const std::vector> & { + return variableTable.getConsts(); + } ///< 获取常量列表 + void enterNewScope() { variableTable.enterNewScope(); } ///< 进入新的作用域 - std::map *getFunctions() { return &functions; } - std::map *getGlobalValues() { return &globals; } - std::map *getExternalFunctions() { return &externalFunctions; } + void leaveScope() { variableTable.leaveScope(); } ///< 离开作用域 -public: - void print(std::ostream &os) const; -}; // class Module + auto isInGlobalArea() const -> bool { return variableTable.isInGlobalScope(); } ///< 是否位于全局作用域 +}; /*! * @} */ -inline std::ostream &operator<<(std::ostream &os, const Type &type) { - type.print(os); - return os; -} - -inline std::ostream &operator<<(std::ostream &os, const Value &value) { - value.print(os); - return os; -} } // namespace sysy diff --git a/src/include/IRBuilder.h b/src/include/IRBuilder.h index c6d12da..7335ea8 100644 --- a/src/include/IRBuilder.h +++ b/src/include/IRBuilder.h @@ -1,13 +1,25 @@ #pragma once -#include "IR.h" #include -#include +#include +#include +#include +#include +#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 breakBlocks; ///< break目标块列表 std::vector 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 &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 &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 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 &thenArgs, - const std::vector &elseArgs) { - auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs, - elseArgs, block); + } ///< 创建return指令 + auto createUncondBrInst(BasicBlock *thenBlock, const std::vector &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 &dims = {}, - const std::string &name = "") { + } ///< 创建无条件指令 + auto createCondBrInst(Value *condition, BasicBlock *thenBlock, BasicBlock *elseBlock, + const std::vector &thenArgs, const std::vector &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 &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 &indices = {}, - const std::string &name = "") { - auto inst = new LoadInst(pointer, indices, block, name); + } ///< 创建分配指令 + auto createAllocaInstWithoutInsert(Type *type, const std::vector &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 &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 &indices = {}, - const std::string &name = "") { + } ///< 创建load指令 + auto createLaInst(Value *pointer, const std::vector &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 &indices, const std::string &name = "") + -> GetSubArrayInst * { + assert(fatherArray->getLValNumDims() > indices.size()); + std::vector 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(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 &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 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 \ No newline at end of file +} // namespace sysy