更新目录结构,修改IR结构,部分修复IR生成

This commit is contained in:
rain2133
2025-06-20 22:46:04 +08:00
parent 1de8c0e7d7
commit c54543bff3
16 changed files with 1699 additions and 1890 deletions

86
TODO.md Normal file
View File

@@ -0,0 +1,86 @@
要打通从SysY到RISC-V的完整编译流程以下是必须实现的核心模块和关键步骤按编译流程顺序。在你们当前IR生成阶段可以优先实现这些基础模块来快速获得可工作的RISC-V汇编输出
### 1. **前端必须模块**
- **词法/语法分析**(已完成):
- `SysYLexer`/`SysYParser`ANTLR生成的解析器
- **IR生成核心**
- `SysYIRGenerator`将AST转换为中间表示IR
- `IRBuilder`:构建指令和基本块的工具类(你们正在实现的部分)
### 2. **中端必要优化(最小集合)**
| 优化阶段 | 关键作用 | 是否必须 |
|-------------------|----------------------------------|----------|
| `Mem2Reg` | 消除冗余内存访问转换为SSA形式 | ✅ 核心 |
| `DCE` (死代码消除) | 移除无用指令 | ✅ 必要 |
| `DFE` (死函数消除) | 移除未使用的函数 | ✅ 必要 |
| `FuncAnalysis` | 函数调用关系分析 | ✅ 基础 |
| `Global2Local` | 全局变量降级为局部变量 | ✅ 重要 |
### 3. **后端核心流程(必须实现)**
```mermaid
graph LR
A[IR指令选择] --> B[寄存器分配]
B --> C[指令调度]
C --> D[汇编生成]
```
1. **指令选择**(关键步骤):
- `DAGBuilder`将IR转换为有向无环图DAG
- `DAGCoverage`DAG到目标指令的映射
- `Mid2End`IR到机器指令的转换接口
2. **寄存器分配**
- `RegisterAlloc`:基础寄存器分配器(可先实现简单算法如线性扫描)
3. **汇编生成**
- `RiscvPrinter`将机器指令输出为RISC-V汇编
- 实现基础指令集:`add`/`sub`/`lw`/`sw`/`beq`/`jal`
### 4. **最小可工作流程**
```cpp
// 精简版编译流程(跳过复杂优化)
int main() {
// 1. 前端解析
auto module = sysy::SysYIRGenerator().genIR(input);
// 2. 关键中端优化
sysy::Mem2Reg(module).run(); // 必须
sysy::Global2Local(module).run(); // 必须
sysy::DCE(module).run(); // 推荐
// 3. 后端代码生成
auto backendModule = mid2end::CodeGenerater().run(module);
riscv::RiscvPrinter().print("output.s", backendModule);
}
```
### 5. **当前开发优先级建议**
1. **完成IR生成**
- 确保能构建基本块、函数、算术/内存/控制流指令
- 实现`createCall`/`createLoad`/`createStore`等核心方法
2. **实现Mem2Reg**
- 插入Phi节点
- 变量重命名(关键算法)
3. **构建基础后端**
- 指令选择实现IR到RISC-V的简单映射例如`IRAdd``add`
- 寄存器分配:使用无限寄存器方案(后期替换为真实分配)
- 汇编打印:支持基础指令输出
> **注意**:循环优化、函数内联、高级寄存器分配等可在基础流程打通后逐步添加。初期可跳过复杂优化。
### 6. 调试建议
- 添加IR打印模块`SysYPrinter`)验证前端输出
- 使用简化测试用例:
```c
int main() {
int a = 1;
int b = a + 2;
return b;
}
```
- 逐步扩展支持:
1. 算术运算 → 2. 条件分支 → 3. 函数调用 → 4. 数组访问
通过聚焦这些核心模块你们可以快速打通从SysY到RISC-V的基础编译流程后续再逐步添加优化传递提升代码质量。

View File

@@ -20,7 +20,7 @@ add_executable(sysyc
# LLVMIRGenerator.cpp # LLVMIRGenerator.cpp
LLVMIRGenerator_1.cpp LLVMIRGenerator_1.cpp
) )
target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_options(sysyc PRIVATE -frtti) target_compile_options(sysyc PRIVATE -frtti)
target_link_libraries(sysyc PRIVATE SysYParser) target_link_libraries(sysyc PRIVATE SysYParser)

View File

@@ -1,586 +1,310 @@
#pragma once
#include "IR.h" #include "IR.h"
#include "range.h"
#include <algorithm>
#include <cassert> #include <cassert>
#include <cstddef>
#include <functional>
#include <iostream>
#include <iterator>
#include <map>
#include <memory> #include <memory>
#include <ostream> #include <sstream>
#include <set>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include <variant>
#include <iomanip>
using namespace std;
namespace sysy { namespace sysy {
template <typename T> class IRBuilder {
ostream &interleave(ostream &os, const T &container, const string sep = ", ") { private:
auto b = container.begin(), e = container.end(); unsigned labelIndex; ///< 基本块标签编号
if (b == e) unsigned tmpIndex; ///< 临时变量编号
return os;
os << *b;
for (b = next(b); b != e; b = next(b))
os << sep << *b;
return os;
}
static inline ostream &printVarName(ostream &os, const Value *var) {
return os << (dyncast<GlobalValue>(var) ? '@' : '%')
<< var->getName();
}
static inline ostream &printBlockName(ostream &os, const BasicBlock *block) {
return os << '^' << block->getName();
}
static inline ostream &printFunctionName(ostream &os, const Function *fn) {
return os << '@' << fn->getName();
}
static inline ostream &printOperand(ostream &os, const Value *value) {
auto constant = dyncast<ConstantValue>(value);
if (constant) {
constant->print(os);
return os;
}
return printVarName(os, value);
}
//===----------------------------------------------------------------------===//
// Types
//===----------------------------------------------------------------------===//
Type *Type::getIntType() { BasicBlock *block; ///< 当前基本块
static Type intType(kInt); BasicBlock::iterator position; ///< 当前基本块指令列表位置的迭代器
return &intType;
}
Type *Type::getFloatType() { std::vector<BasicBlock *> trueBlocks; ///< true分支基本块列表
static Type floatType(kFloat); std::vector<BasicBlock *> falseBlocks; ///< false分支基本块列表
return &floatType;
}
Type *Type::getVoidType() { std::vector<BasicBlock *> breakBlocks; ///< break目标块列表
static Type voidType(kVoid); std::vector<BasicBlock *> continueBlocks; ///< continue目标块列表
return &voidType;
}
Type *Type::getLabelType() { public:
static Type labelType(kLabel); IRBuilder() : labelIndex(0), tmpIndex(0), block(nullptr) {}
return &labelType; 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) {}
Type *Type::getPointerType(Type *baseType) { public:
// forward to PointerType unsigned getLabelIndex() { return labelIndex++; }
return PointerType::get(baseType); unsigned getTmpIndex() { return tmpIndex++; }
}
Type *Type::getFunctionType(Type *returnType,
const vector<Type *> &paramTypes) {
// forward to FunctionType
return FunctionType::get(returnType, paramTypes);
}
Type *Type::getArrayType(Type *elementType, const vector<int> &dims) {
// forward to ArrayType
return ArrayType::get(elementType, dims);
}
ArrayType* Type::asArrayType() const {
return isArray() ? dynamic_cast<ArrayType*>(const_cast<Type*>(this)) : nullptr;
}
int Type::getSize() const {
switch (kind) {
case kInt:
case kFloat:
return 4;
case kLabel:
case kPointer:
case kFunction:
return 8;
case kVoid:
return 0;
case kArray:
return asArrayType()->getArraySize();
}
return 0;
}
void Type::print(ostream &os) const {
auto kind = getKind();
switch (kind) {
case kInt:
os << "int";
break;
case kFloat:
os << "float";
break;
case kVoid:
os << "void";
break;
case kPointer:
static_cast<const PointerType *>(this)->getBaseType()->print(os);
os << "*";
break;
case kFunction:
static_cast<const FunctionType *>(this)->getReturnType()->print(os);
os << "(";
interleave(os, static_cast<const FunctionType *>(this)->getParamTypes());
os << ")";
break;
case kLabel:
default:
cerr << "Unexpected type!\n";
break;
}
}
PointerType *PointerType::get(Type *baseType) {
static std::map<Type *, std::unique_ptr<PointerType>> pointerTypes;
auto iter = pointerTypes.find(baseType);
if (iter != pointerTypes.end())
return iter->second.get();
auto type = new PointerType(baseType);
assert(type);
auto result = pointerTypes.emplace(baseType, type);
return result.first->second.get();
}
FunctionType *FunctionType::get(Type *returnType,
const std::vector<Type *> &paramTypes) {
static std::set<std::unique_ptr<FunctionType>> functionTypes;
auto iter =
std::find_if(functionTypes.begin(), functionTypes.end(),
[&](const std::unique_ptr<FunctionType> &type) -> bool {
if (returnType != type->getReturnType() or
paramTypes.size() != type->getParamTypes().size())
return false;
return std::equal(paramTypes.begin(), paramTypes.end(),
type->getParamTypes().begin());
});
if (iter != functionTypes.end())
return iter->get();
auto type = new FunctionType(returnType, paramTypes);
assert(type);
auto result = functionTypes.emplace(type);
return result.first->get();
}
void Value::replaceAllUsesWith(Value *value) {
for (auto &use : uses)
use->getUser()->setOperand(use->getIndex(), value);
uses.clear();
}
bool Value::isConstant() const {
if (dyncast<ConstantValue>(this))
return true;
if (dyncast<GlobalValue>(this) or
dyncast<Function>(this))
return true;
// if (auto array = dyncast<const ArrayValue *>(this)) {
// auto elements = array->getValues();
// return all_of(elements.begin(), elements.end(),
// [](Value *v) -> bool { return v->isConstant(); });
// }
return false;
}
// 定义静态常量池
std::unordered_map<ConstantValueKey, ConstantValue*, ConstantValue::ConstantValueHash> ConstantValue::constantPool;
// 常量池实现
ConstantValue* ConstantValue::get(Type* type, int32_t value) {
ConstantValueKey key = {type, ConstantValVariant(value)};
if (auto it = constantPool.find(key); it != constantPool.end()) { BasicBlock *getBasicBlock() const { return block; }
return it->second; BasicBlock::iterator getPosition() const { return position; }
}
ConstantValue* constant = new ConstantInt(type, value); void setPosition(BasicBlock *block, BasicBlock::iterator position) {
constantPool[key] = constant; this->block = block;
return constant; this->position = position;
}
ConstantValue* ConstantValue::get(Type* type, float value) {
ConstantValueKey key = {type, ConstantValVariant(value)};
if (auto it = constantPool.find(key); it != constantPool.end()) {
return it->second;
} }
void setPosition(BasicBlock::iterator position) { this->position = position; }
ConstantValue* constant = new ConstantFloat(type, value);
constantPool[key] = constant;
return constant;
}
ConstantValue* ConstantValue::getInt32(int32_t value) { // 控制流管理函数
return get(Type::getIntType(), value); BasicBlock *getBreakBlock() const { return breakBlocks.back(); }
} BasicBlock *popBreakBlock() {
auto result = breakBlocks.back();
ConstantValue* ConstantValue::getFloat32(float value) { breakBlocks.pop_back();
return get(Type::getFloatType(), value); return result;
}
ConstantValue* ConstantValue::getTrue() {
return get(Type::getIntType(), 1);
}
ConstantValue* ConstantValue::getFalse() {
return get(Type::getIntType(), 0);
}
void ConstantValue::print(std::ostream &os) const {
// 根据类型调用相应的打印实现
if (auto intConst = dynamic_cast<const ConstantInt*>(this)) {
intConst->print(os);
}
else if (auto floatConst = dynamic_cast<const ConstantFloat*>(this)) {
floatConst->print(os);
} }
else { BasicBlock *getContinueBlock() const { return continueBlocks.back(); }
os << "???"; // 未知常量类型 BasicBlock *popContinueBlock() {
auto result = continueBlocks.back();
continueBlocks.pop_back();
return result;
} }
} BasicBlock *getTrueBlock() const { return trueBlocks.back(); }
BasicBlock *getFalseBlock() const { return falseBlocks.back(); }
void ConstantInt::print(std::ostream &os) const { BasicBlock *popTrueBlock() {
os << value; auto result = trueBlocks.back();
} trueBlocks.pop_back();
void ConstantFloat::print(std::ostream &os) const { return result;
if (value == static_cast<int>(value)) {
os << value << ".0"; // 确保输出带小数点
} else {
os << std::fixed << std::setprecision(6) << value;
} }
} 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); }
Argument::Argument(Type *type, BasicBlock *block, int index, public:
const std::string &name) // 指令创建函数
: Value(kArgument, type, name), block(block), index(index) { Instruction *insertInst(Instruction *inst) {
if (not hasName()) assert(inst);
setName(to_string(block->getParent()->allocateVariableID())); block->getInstructions().emplace(position, inst);
} return inst;
}
void Argument::print(std::ostream &os) const { UnaryInst *createUnaryInst(Instruction::Kind kind, Type *type, Value *operand,
assert(hasName()); const std::string &name = "") {
printVarName(os, this) << ": " << *getType(); auto inst = new UnaryInst(kind, type, operand, block, name);
} return static_cast<UnaryInst*>(insertInst(inst));
}
BasicBlock::BasicBlock(Function *parent, const std::string &name) UnaryInst *createNegInst(Value *operand, const std::string &name = "") {
: Value(kBasicBlock, Type::getLabelType(), name), parent(parent), return createUnaryInst(Instruction::kNeg, Type::getIntType(), operand, name);
instructions(), arguments(), successors(), predecessors() { }
if (not hasName())
setName("bb" + to_string(getParent()->allocateblockID()));
}
void BasicBlock::print(std::ostream &os) const { UnaryInst *createNotInst(Value *operand, const std::string &name = "") {
assert(hasName()); return createUnaryInst(Instruction::kNot, Type::getIntType(), operand, name);
os << " "; }
printBlockName(os, this);
auto args = getArguments(); UnaryInst *createFtoIInst(Value *operand, const std::string &name = "") {
auto b = args.begin(), e = args.end(); return createUnaryInst(Instruction::kFtoI, Type::getIntType(), operand, name);
if (b != e) { }
os << '(';
printVarName(os, b->get()) << ": " << *b->get()->getType(); UnaryInst *createBitFtoIInst(Value *operand, const std::string &name = "") {
for (auto &arg : make_range(std::next(b), e)) { return createUnaryInst(Instruction::kBitFtoI, Type::getIntType(), operand, name);
os << ", "; }
printVarName(os, arg.get()) << ": " << *arg->getType();
UnaryInst *createFNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNeg, Type::getFloatType(), operand, name);
}
UnaryInst *createFNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNot, Type::getIntType(), operand, name);
}
UnaryInst *createIToFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand, name);
}
UnaryInst *createBitItoFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kBitItoF, Type::getFloatType(), operand, name);
}
BinaryInst *createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs,
Value *rhs, const std::string &name = "") {
auto inst = new BinaryInst(kind, type, lhs, rhs, block, name);
return static_cast<BinaryInst*>(insertInst(inst));
}
BinaryInst *createAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAdd, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kSub, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kMul, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kDiv, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createRemInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kRem, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpEQ, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpNE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createICmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFAdd, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFSub, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFMul, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFDiv, Type::getFloatType(), lhs, rhs, name);
}
BinaryInst *createFCmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpEQ, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpNE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGT, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createFCmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGE, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createAndInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAnd, Type::getIntType(), lhs, rhs, name);
}
BinaryInst *createOrInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kOr, Type::getIntType(), lhs, rhs, name);
}
CallInst *createCallInst(Function *callee, const std::vector<Value *> &args,
const std::string &name = "") {
auto inst = new CallInst(callee, args, block, name);
return static_cast<CallInst*>(insertInst(inst));
}
ReturnInst *createReturnInst(Value *value = nullptr) {
auto inst = new ReturnInst(value, block);
return static_cast<ReturnInst*>(insertInst(inst));
}
UncondBrInst *createUncondBrInst(BasicBlock *thenBlock,
const std::vector<Value *> &args) {
auto inst = new UncondBrInst(thenBlock, args, block);
return static_cast<UncondBrInst*>(insertInst(inst));
}
CondBrInst *createCondBrInst(Value *condition, BasicBlock *thenBlock,
BasicBlock *elseBlock,
const std::vector<Value *> &thenArgs,
const std::vector<Value *> &elseArgs) {
auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs, elseArgs, block);
return static_cast<CondBrInst*>(insertInst(inst));
}
AllocaInst *createAllocaInst(Type *type, const std::vector<Value *> &dims = {},
const std::string &name = "") {
auto inst = new AllocaInst(type, dims, block, name);
return static_cast<AllocaInst*>(insertInst(inst));
}
AllocaInst *createAllocaInstWithoutInsert(Type *type,
const std::vector<Value *> &dims = {},
BasicBlock *parent = nullptr,
const std::string &name = "") {
return new AllocaInst(type, dims, parent, name);
}
LoadInst *createLoadInst(Value *pointer, const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new LoadInst(pointer, indices, block, name);
return static_cast<LoadInst*>(insertInst(inst));
}
LaInst *createLaInst(Value *pointer, const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new LaInst(pointer, indices, block, name);
return static_cast<LaInst*>(insertInst(inst));
}
GetSubArrayInst *createGetSubArray(LVal *fatherArray,
const std::vector<Value *> &indices,
const std::string &name = "") {
assert(fatherArray->getLValNumDims() > indices.size());
std::vector<Value *> subDims;
auto dims = fatherArray->getLValDims();
auto iter = std::next(dims.begin(), indices.size());
while (iter != dims.end()) {
subDims.emplace_back(*iter);
iter++;
} }
os << ')';
auto fatherArrayValue = dynamic_cast<Value *>(fatherArray);
AllocaInst * childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block);
auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block ,name);
return static_cast<GetSubArrayInst*>(insertInst(inst));
} }
os << ":\n";
for (auto &inst : instructions) { MemsetInst *createMemsetInst(Value *pointer, Value *begin, Value *size,
os << " " << *inst << '\n'; Value *value, const std::string &name = "") {
auto inst = new MemsetInst(pointer, begin, size, value, block, name);
return static_cast<MemsetInst*>(insertInst(inst));
} }
}
Instruction::Instruction(Kind kind, Type *type, BasicBlock *parent, StoreInst *createStoreInst(Value *value, Value *pointer,
const std::string &name) const std::vector<Value *> &indices = {},
: User(kind, type, name), kind(kind), parent(parent) { const std::string &name = "") {
if (not type->isVoid() and not hasName()) auto inst = new StoreInst(value, pointer, indices, block, name);
setName(to_string(getFunction()->allocateVariableID())); return static_cast<StoreInst*>(insertInst(inst));
}
void CallInst::print(std::ostream &os) const {
if (not getType()->isVoid())
printVarName(os, this) << " = call ";
printFunctionName(os, getCallee()) << '(';
auto args = getArguments();
auto b = args.begin(), e = args.end();
if (b != e) {
printOperand(os, *b);
for (auto arg : make_range(std::next(b), e)) {
os << ", ";
printOperand(os, arg);
}
} }
os << ") : " << *getType();
}
void UnaryInst::print(std::ostream &os) const { PhiInst *createPhiInst(Type *type, Value *lhs, BasicBlock *parent,
printVarName(os, this) << " = "; const std::string &name = "") {
switch (getKind()) { auto predNum = parent->getNumPredecessors();
case kNeg: std::vector<Value *> rhs(predNum, lhs);
os << "neg"; auto inst = new PhiInst(type, lhs, rhs, lhs, parent, name);
break; parent->getInstructions().emplace(parent->begin(), inst);
case kNot: return inst;
os << "not";
break;
case kFNeg:
os << "fneg";
break;
case kFtoI:
os << "ftoi";
break;
case kIToF:
os << "itof";
break;
default:
assert(false);
} }
printOperand(os, getOperand()) << " : " << *getType(); };
}
void BinaryInst::print(std::ostream &os) const { } // namespace sysy
printVarName(os, this) << " = ";
switch (getKind()) {
case kAdd:
os << "add";
break;
case kSub:
os << "sub";
break;
case kMul:
os << "mul";
break;
case kDiv:
os << "div";
break;
case kRem:
os << "rem";
break;
case kICmpEQ:
os << "icmpeq";
break;
case kICmpNE:
os << "icmpne";
break;
case kICmpLT:
os << "icmplt";
break;
case kICmpGT:
os << "icmpgt";
break;
case kICmpLE:
os << "icmple";
break;
case kICmpGE:
os << "icmpge";
break;
case kFAdd:
os << "fadd";
break;
case kFSub:
os << "fsub";
break;
case kFMul:
os << "fmul";
break;
case kFDiv:
os << "fdiv";
break;
case kFRem:
os << "frem";
break;
case kFCmpEQ:
os << "fcmpeq";
break;
case kFCmpNE:
os << "fcmpne";
break;
case kFCmpLT:
os << "fcmplt";
break;
case kFCmpGT:
os << "fcmpgt";
break;
case kFCmpLE:
os << "fcmple";
break;
case kFCmpGE:
os << "fcmpge";
break;
default:
assert(false);
}
os << ' ';
printOperand(os, getLhs()) << ", ";
printOperand(os, getRhs()) << " : " << *getType();
}
void ReturnInst::print(std::ostream &os) const {
os << "return";
if (auto value = getReturnValue()) {
os << ' ';
printOperand(os, value) << " : " << *value->getType();
}
}
void UncondBrInst::print(std::ostream &os) const {
os << "br ";
printBlockName(os, getBlock());
auto args = getArguments();
auto b = args.begin(), e = args.end();
if (b != e) {
os << '(';
printOperand(os, *b);
for (auto arg : make_range(std::next(b), e)) {
os << ", ";
printOperand(os, arg);
}
os << ')';
}
}
void CondBrInst::print(std::ostream &os) const {
os << "condbr ";
printOperand(os, getCondition()) << ", ";
printBlockName(os, getThenBlock());
{
auto args = getThenArguments();
auto b = args.begin(), e = args.end();
if (b != e) {
os << '(';
printOperand(os, *b);
for (auto arg : make_range(std::next(b), e)) {
os << ", ";
printOperand(os, arg);
}
os << ')';
}
}
os << ", ";
printBlockName(os, getElseBlock());
{
auto args = getElseArguments();
auto b = args.begin(), e = args.end();
if (b != e) {
os << '(';
printOperand(os, *b);
for (auto arg : make_range(std::next(b), e)) {
os << ", ";
printOperand(os, arg);
}
os << ')';
}
}
}
void AllocaInst::print(std::ostream &os) const {
if (getNumDims())
cerr << "not implemented yet\n";
printVarName(os, this) << " = ";
os << "alloca "
<< *static_cast<const PointerType *>(getType())->getBaseType();
os << " : " << *getType();
}
void LoadInst::print(std::ostream &os) const {
if (getNumIndices())
cerr << "not implemented yet\n";
printVarName(os, this) << " = ";
os << "load ";
printOperand(os, getPointer()) << " : " << *getType();
}
void StoreInst::print(std::ostream &os) const {
if (getNumIndices())
cerr << "not implemented yet\n";
os << "store ";
printOperand(os, getValue()) << ", ";
printOperand(os, getPointer()) << " : " << *getValue()->getType();
}
void Function::print(std::ostream &os) const {
auto returnType = getReturnType();
auto paramTypes = getParamTypes();
os << *returnType << ' ';
printFunctionName(os, this) << '(';
auto b = paramTypes.begin(), e = paramTypes.end();
if (b != e) {
os << *(*b);
for (auto type : make_range(std::next(b), e))
os << ", " << *type;
}
os << ") {\n";
for (auto &bb : getBasicBlocks()) {
os << *bb << '\n';
}
os << "}";
}
void Module::print(std::ostream &os) const {
for (auto &value : children)
os << *value << '\n';
}
// ArrayValue *ArrayValue::get(Type *type, const vector<Value *> &values) {
// static map<pair<Type *, size_t>, unique_ptr<ArrayValue>> arrayConstants;
// hash<string> hasher;
// auto key = make_pair(
// type, hasher(string(reinterpret_cast<const char *>(values.data()),
// values.size() * sizeof(Value *))));
// auto iter = arrayConstants.find(key);
// if (iter != arrayConstants.end())
// return iter->second.get();
// auto constant = new ArrayValue(type, values);
// assert(constant);
// auto result = arrayConstants.emplace(key, constant);
// return result.first->second.get();
// }
// ArrayValue *ArrayValue::get(const std::vector<int> &values) {
// vector<Value *> vals(values.size(), nullptr);
// std::transform(values.begin(), values.end(), vals.begin(),
// [](int v) { return ConstantValue::get(v); });
// return get(Type::getIntType(), vals);
// }
// ArrayValue *ArrayValue::get(const std::vector<float> &values) {
// vector<Value *> vals(values.size(), nullptr);
// std::transform(values.begin(), values.end(), vals.begin(),
// [](float v) { return ConstantValue::get(v); });
// return get(Type::getFloatType(), vals);
// }
void User::setOperand(int index, Value *value) {
assert(index < getNumOperands());
operands[index].setValue(value);
}
void User::replaceOperand(int index, Value *value) {
assert(index < getNumOperands());
auto &use = operands[index];
use.getValue()->removeUse(&use);
use.setValue(value);
}
CallInst::CallInst(Function *callee, const std::vector<Value *> &args,
BasicBlock *parent, const std::string &name)
: Instruction(kCall, callee->getReturnType(), parent, name) {
addOperand(callee);
for (auto arg : args)
addOperand(arg);
}
Function *CallInst::getCallee() const {
return dyncast<Function>(getOperand(0));
}
} // namespace sysy

1120
src/IR.h

File diff suppressed because it is too large Load Diff

0
src/SysYIRAnalyser.cpp Normal file
View File

View File

@@ -834,204 +834,4 @@ std::any SysYIRGenerator::visitConstExp(SysYParser::ConstExpContext* ctx) {
return res; return res;
} }
/* begin
std::any SysYIRGenerator::visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type) {
std::vector<Value *> values;
for (auto constDef : ctx->constDef()) {
auto name = constDef->Ident()->getText();
// get its dimensions
vector<Value *> dims;
for (auto dim : constDef->constExp())
dims.push_back(any_cast<Value *>(dim->accept(this)));
if (dims.size() == 0) {
auto init = constDef->ASSIGN() ? any_cast<Value *>((constDef->constInitVal()->constExp()->accept(this)))
: nullptr;
if (init && isa<ConstantValue>(init)){
Type *btype = type->as<PointerType>()->getBaseType();
if (btype->isInt() && init->getType()->isFloat())
init = ConstantValue::get((int)dynamic_cast<ConstantValue *>(init)->getFloat());
else if (btype->isFloat() && init->getType()->isInt())
init = ConstantValue::get((float)dynamic_cast<ConstantValue *>(init)->getInt());
}
auto global_value = module->createGlobalValue(name, type, dims, init);
symbols_table.insert(name, global_value);
values.push_back(global_value);
}
else{
auto init = constDef->ASSIGN() ? any_cast<Value *>(dims[0])
: nullptr;
auto global_value = module->createGlobalValue(name, type, dims, init);
if (constDef->ASSIGN()) {
d = 0;
n = 0;
path.clear();
path = vector<int>(dims.size(), 0);
isalloca = false;
current_type = global_value->getType()->as<PointerType>()->getBaseType();
current_global = global_value;
numdims = global_value->getNumDims();
for (auto init : constDef->constInitVal()->constInitVal())
init->accept(this);
// visitConstInitValue(init);
}
symbols_table.insert(name, global_value);
values.push_back(global_value);
}
}
return values;
}
std::any SysYIRGenerator::visitVarGlobalDecl(SysYParser::VarDeclContext *ctx, Type* type){
std::vector<Value *> values;
for (auto varDef : ctx->varDef()) {
auto name = varDef->Ident()->getText();
// get its dimensions
vector<Value *> dims;
for (auto dim : varDef->constExp())
dims.push_back(any_cast<Value *>(dim->accept(this)));
if (dims.size() == 0) {
auto init = varDef->ASSIGN() ? any_cast<Value *>((varDef->initVal()->exp()->accept(this)))
: nullptr;
if (init && isa<ConstantValue>(init)){
Type *btype = type->as<PointerType>()->getBaseType();
if (btype->isInt() && init->getType()->isFloat())
init = ConstantValue::get((int)dynamic_cast<ConstantValue *>(init)->getFloat());
else if (btype->isFloat() && init->getType()->isInt())
init = ConstantValue::get((float)dynamic_cast<ConstantValue *>(init)->getInt());
}
auto global_value = module->createGlobalValue(name, type, dims, init);
symbols_table.insert(name, global_value);
values.push_back(global_value);
}
else{
auto init = varDef->ASSIGN() ? any_cast<Value *>(dims[0])
: nullptr;
auto global_value = module->createGlobalValue(name, type, dims, init);
if (varDef->ASSIGN()) {
d = 0;
n = 0;
path.clear();
path = vector<int>(dims.size(), 0);
isalloca = false;
current_type = global_value->getType()->as<PointerType>()->getBaseType();
current_global = global_value;
numdims = global_value->getNumDims();
for (auto init : varDef->initVal()->initVal())
init->accept(this);
// visitInitValue(init);
}
symbols_table.insert(name, global_value);
values.push_back(global_value);
}
}
return values;
}
std::any SysYIRGenerator::visitConstLocalDecl(SysYParser::ConstDeclContext *ctx, Type* type){
std::vector<Value *> values;
// handle variables
for (auto constDef : ctx->constDef()) {
auto name = constDef->Ident()->getText();
vector<Value *> dims;
for (auto dim : constDef->constExp())
dims.push_back(any_cast<Value *>(dim->accept(this)));
auto alloca = builder.createAllocaInst(type, dims, name);
symbols_table.insert(name, alloca);
if (constDef->ASSIGN()) {
if (alloca->getNumDims() == 0) {
auto value = any_cast<Value *>(constDef->constInitVal()->constExp()->accept(this));
if (isa<ConstantValue>(value)) {
if (ctx->bType()->INT() && dynamic_cast<ConstantValue *>(value)->isFloat())
value = ConstantValue::get((int)dynamic_cast<ConstantValue *>(value)->getFloat());
else if (ctx->bType()->FLOAT() && dynamic_cast<ConstantValue *>(value)->isInt())
value = ConstantValue::get((float)dynamic_cast<ConstantValue *>(value)->getInt());
}
else if (alloca->getType()->as<PointerType>()->getBaseType()->isInt() && value->getType()->isFloat())
value = builder.createFtoIInst(value);
else if (alloca->getType()->as<PointerType>()->getBaseType()->isFloat() && value->getType()->isInt())
value = builder.createIToFInst(value);
auto store = builder.createStoreInst(value, alloca);
}
else{
d = 0;
n = 0;
path.clear();
path = vector<int>(alloca->getNumDims(), 0);
isalloca = true;
current_alloca = alloca;
current_type = alloca->getType()->as<PointerType>()->getBaseType();
numdims = alloca->getNumDims();
for (auto init : constDef->constInitVal()->constInitVal())
init->accept(this);
}
}
values.push_back(alloca);
}
return values;
}
std::any SysYIRGenerator::visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Type* type){
std::vector<Value *> values;
for (auto varDef : ctx->varDef()) {
auto name = varDef->Ident()->getText();
vector<Value *> dims;
for (auto dim : varDef->constExp())
dims.push_back(any_cast<Value *>(dim->accept(this)));
auto alloca = builder.createAllocaInst(type, dims, name);
symbols_table.insert(name, alloca);
if (varDef->ASSIGN()) {
if (alloca->getNumDims() == 0) {
auto value = any_cast<Value *>(varDef->initVal()->exp()->accept(this));
if (isa<ConstantValue>(value)) {
if (ctx->bType()->INT() && dynamic_cast<ConstantValue *>(value)->isFloat())
value = ConstantValue::get((int)dynamic_cast<ConstantValue *>(value)->getFloat());
else if (ctx->bType()->FLOAT() && dynamic_cast<ConstantValue *>(value)->isInt())
value = ConstantValue::get((float)dynamic_cast<ConstantValue *>(value)->getInt());
}
else if (alloca->getType()->as<PointerType>()->getBaseType()->isInt() && value->getType()->isFloat())
value = builder.createFtoIInst(value);
else if (alloca->getType()->as<PointerType>()->getBaseType()->isFloat() && value->getType()->isInt())
value = builder.createIToFInst(value);
auto store = builder.createStoreInst(value, alloca);
}
else{
d = 0;
n = 0;
path.clear();
path = vector<int>(alloca->getNumDims(), 0);
isalloca = true;
current_alloca = alloca;
current_type = alloca->getType()->as<PointerType>()->getBaseType();
numdims = alloca->getNumDims();
for (auto init : varDef->initVal()->initVal())
init->accept(this);
}
}
values.push_back(alloca);
}
return values;
}
end
*/
} // namespace sysy } // namespace sysy

1319
src/include/IR.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -8,14 +8,23 @@ namespace sysy {
class IRBuilder { class IRBuilder {
private: private:
BasicBlock *block; unsigned labelIndex; ///< 基本块标签编号
BasicBlock::iterator position; unsigned tmpIndex; ///< 临时变量编号
BasicBlock *block; ///< 当前基本块
BasicBlock::iterator position; ///< 当前基本块指令列表位置的迭代器
std::vector<BasicBlock *> trueBlocks; ///< true分支基本块列表
std::vector<BasicBlock *> falseBlocks; ///< false分支基本块列表
std::vector<BasicBlock *> breakBlocks; ///< break目标块列表
std::vector<BasicBlock *> continueBlocks; ///< continue目标块列表
public: public:
IRBuilder() = default; IRBuilder() : labelIndex(0), tmpIndex(0), block(nullptr) {}
IRBuilder(BasicBlock *block) : block(block), position(block->end()) {} explicit IRBuilder(BasicBlock *block) : labelIndex(0), tmpIndex(0), block(block), position(block->end()) {}
IRBuilder(BasicBlock *block, BasicBlock::iterator position) IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: block(block), position(position) {} : labelIndex(0), tmpIndex(0), block(block), position(position) {}
public: public:
BasicBlock *getBasicBlock() const { return block; } BasicBlock *getBasicBlock() const { return block; }
@@ -60,7 +69,7 @@ public:
name); name);
} }
UnaryInst *createIToFInst(Value *operand, const std::string &name = "") { UnaryInst *createIToFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kIToF, Type::getFloatType(), operand, return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand,
name); name);
} }
BinaryInst *createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs, BinaryInst *createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs,

View File

View File

@@ -134,15 +134,6 @@ public:
std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override; std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override;
std::any visitConstExp(SysYParser::ConstExpContext *ctx) override; std::any visitConstExp(SysYParser::ConstExpContext *ctx) override;
private:
std::any visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type);
std::any visitVarGlobalDecl(SysYParser::VarDeclContext *ctx, Type* type);
std::any visitConstLocalDecl(SysYParser::ConstDeclContext *ctx, Type* type);
std::any visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Type* type);
Type *getArithmeticResultType(Type *lhs, Type *rhs) {
assert(lhs->isIntOrFloat() and rhs->isIntOrFloat());
return lhs == rhs ? lhs : Type::getFloatType();
}
}; // class SysYIRGenerator }; // class SysYIRGenerator