Merge branch 'midend' into backend-float
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#include "PreRA_Scheduler.h"
|
#include "PreRA_Scheduler.h"
|
||||||
#include "RISCv64LLIR.h"
|
#include "RISCv64LLIR.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define MAX_SCHEDULING_BLOCK_SIZE 1000 // 严格限制调度块大小
|
#define MAX_SCHEDULING_BLOCK_SIZE 1000 // 严格限制调度块大小
|
||||||
@@ -66,9 +66,44 @@ static bool hasMemoryAccess(MachineInstr *instr) {
|
|||||||
return isLoadInstr(instr) || isStoreInstr(instr);
|
return isLoadInstr(instr) || isStoreInstr(instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取指令定义的虚拟寄存器
|
// 获取内存访问位置信息
|
||||||
static std::set<unsigned> getDefinedVirtualRegisters(MachineInstr *instr) {
|
struct MemoryLocation {
|
||||||
std::set<unsigned> defined_regs;
|
unsigned base_reg;
|
||||||
|
int64_t offset;
|
||||||
|
bool is_valid;
|
||||||
|
|
||||||
|
MemoryLocation() : base_reg(0), offset(0), is_valid(false) {}
|
||||||
|
MemoryLocation(unsigned base, int64_t off)
|
||||||
|
: base_reg(base), offset(off), is_valid(true) {}
|
||||||
|
|
||||||
|
bool operator==(const MemoryLocation &other) const {
|
||||||
|
return is_valid && other.is_valid && base_reg == other.base_reg &&
|
||||||
|
offset == other.offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 缓存指令分析信息
|
||||||
|
struct InstrInfo {
|
||||||
|
std::unordered_set<unsigned> defined_regs;
|
||||||
|
std::unordered_set<unsigned> used_regs;
|
||||||
|
MemoryLocation mem_location;
|
||||||
|
bool is_load;
|
||||||
|
bool is_store;
|
||||||
|
bool is_terminator;
|
||||||
|
bool is_call;
|
||||||
|
bool has_side_effect;
|
||||||
|
bool has_memory_access;
|
||||||
|
|
||||||
|
InstrInfo() : is_load(false), is_store(false), is_terminator(false),
|
||||||
|
is_call(false), has_side_effect(false), has_memory_access(false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 指令信息缓存
|
||||||
|
static std::unordered_map<MachineInstr*, InstrInfo> instr_info_cache;
|
||||||
|
|
||||||
|
// 获取指令定义的虚拟寄存器 - 优化版本
|
||||||
|
static std::unordered_set<unsigned> getDefinedVirtualRegisters(MachineInstr *instr) {
|
||||||
|
std::unordered_set<unsigned> defined_regs;
|
||||||
RVOpcodes opcode = instr->getOpcode();
|
RVOpcodes opcode = instr->getOpcode();
|
||||||
|
|
||||||
// CALL指令可能定义返回值寄存器
|
// CALL指令可能定义返回值寄存器
|
||||||
@@ -101,9 +136,9 @@ static std::set<unsigned> getDefinedVirtualRegisters(MachineInstr *instr) {
|
|||||||
return defined_regs;
|
return defined_regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取指令使用的虚拟寄存器
|
// 获取指令使用的虚拟寄存器 - 优化版本
|
||||||
static std::set<unsigned> getUsedVirtualRegisters(MachineInstr *instr) {
|
static std::unordered_set<unsigned> getUsedVirtualRegisters(MachineInstr *instr) {
|
||||||
std::set<unsigned> used_regs;
|
std::unordered_set<unsigned> used_regs;
|
||||||
RVOpcodes opcode = instr->getOpcode();
|
RVOpcodes opcode = instr->getOpcode();
|
||||||
|
|
||||||
// CALL指令:跳过第一个操作数(返回值),其余为参数
|
// CALL指令:跳过第一个操作数(返回值),其余为参数
|
||||||
@@ -164,22 +199,6 @@ static std::set<unsigned> getUsedVirtualRegisters(MachineInstr *instr) {
|
|||||||
return used_regs;
|
return used_regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取内存访问位置信息
|
|
||||||
struct MemoryLocation {
|
|
||||||
unsigned base_reg;
|
|
||||||
int64_t offset;
|
|
||||||
bool is_valid;
|
|
||||||
|
|
||||||
MemoryLocation() : base_reg(0), offset(0), is_valid(false) {}
|
|
||||||
MemoryLocation(unsigned base, int64_t off)
|
|
||||||
: base_reg(base), offset(off), is_valid(true) {}
|
|
||||||
|
|
||||||
bool operator==(const MemoryLocation &other) const {
|
|
||||||
return is_valid && other.is_valid && base_reg == other.base_reg &&
|
|
||||||
offset == other.offset;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取内存访问位置
|
// 获取内存访问位置
|
||||||
static MemoryLocation getMemoryLocation(MachineInstr *instr) {
|
static MemoryLocation getMemoryLocation(MachineInstr *instr) {
|
||||||
if (!isLoadInstr(instr) && !isStoreInstr(instr)) {
|
if (!isLoadInstr(instr) && !isStoreInstr(instr)) {
|
||||||
@@ -199,6 +218,27 @@ static MemoryLocation getMemoryLocation(MachineInstr *instr) {
|
|||||||
return MemoryLocation();
|
return MemoryLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预计算并缓存指令信息
|
||||||
|
static const InstrInfo& getInstrInfo(MachineInstr *instr) {
|
||||||
|
auto it = instr_info_cache.find(instr);
|
||||||
|
if (it != instr_info_cache.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstrInfo& info = instr_info_cache[instr];
|
||||||
|
info.defined_regs = getDefinedVirtualRegisters(instr);
|
||||||
|
info.used_regs = getUsedVirtualRegisters(instr);
|
||||||
|
info.mem_location = getMemoryLocation(instr);
|
||||||
|
info.is_load = isLoadInstr(instr);
|
||||||
|
info.is_store = isStoreInstr(instr);
|
||||||
|
info.is_terminator = isTerminatorInstr(instr);
|
||||||
|
info.is_call = isCallInstr(instr);
|
||||||
|
info.has_side_effect = hasSideEffect(instr);
|
||||||
|
info.has_memory_access = hasMemoryAccess(instr);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查两个内存位置是否可能别名
|
// 检查两个内存位置是否可能别名
|
||||||
static bool mayAlias(const MemoryLocation &loc1, const MemoryLocation &loc2) {
|
static bool mayAlias(const MemoryLocation &loc1, const MemoryLocation &loc2) {
|
||||||
if (!loc1.is_valid || !loc2.is_valid) {
|
if (!loc1.is_valid || !loc2.is_valid) {
|
||||||
@@ -214,30 +254,28 @@ static bool mayAlias(const MemoryLocation &loc1, const MemoryLocation &loc2) {
|
|||||||
return loc1.offset == loc2.offset;
|
return loc1.offset == loc2.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查两个指令之间是否存在数据依赖
|
// 检查两个指令之间是否存在数据依赖 - 优化版本
|
||||||
static bool hasDataDependency(MachineInstr *first, MachineInstr *second) {
|
static bool hasDataDependency(MachineInstr *first, MachineInstr *second) {
|
||||||
auto defined_regs_first = getDefinedVirtualRegisters(first);
|
const InstrInfo& info_first = getInstrInfo(first);
|
||||||
auto used_regs_first = getUsedVirtualRegisters(first);
|
const InstrInfo& info_second = getInstrInfo(second);
|
||||||
auto defined_regs_second = getDefinedVirtualRegisters(second);
|
|
||||||
auto used_regs_second = getUsedVirtualRegisters(second);
|
|
||||||
|
|
||||||
// RAW依赖: second读取first写入的寄存器
|
// RAW依赖: second读取first写入的寄存器
|
||||||
for (const auto ® : defined_regs_first) {
|
for (const auto ® : info_first.defined_regs) {
|
||||||
if (used_regs_second.count(reg)) {
|
if (info_second.used_regs.find(reg) != info_second.used_regs.end()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WAR依赖: second写入first读取的寄存器
|
// WAR依赖: second写入first读取的寄存器
|
||||||
for (const auto ® : used_regs_first) {
|
for (const auto ® : info_first.used_regs) {
|
||||||
if (defined_regs_second.count(reg)) {
|
if (info_second.defined_regs.find(reg) != info_second.defined_regs.end()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WAW依赖: 两个指令写入同一寄存器
|
// WAW依赖: 两个指令写入同一寄存器
|
||||||
for (const auto ® : defined_regs_first) {
|
for (const auto ® : info_first.defined_regs) {
|
||||||
if (defined_regs_second.count(reg)) {
|
if (info_second.defined_regs.find(reg) != info_second.defined_regs.end()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,40 +283,41 @@ static bool hasDataDependency(MachineInstr *first, MachineInstr *second) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查两个指令之间是否存在内存依赖
|
// 检查两个指令之间是否存在内存依赖 - 优化版本
|
||||||
static bool hasMemoryDependency(MachineInstr *first, MachineInstr *second) {
|
static bool hasMemoryDependency(MachineInstr *first, MachineInstr *second) {
|
||||||
bool first_accesses_memory = isLoadInstr(first) || isStoreInstr(first);
|
const InstrInfo& info_first = getInstrInfo(first);
|
||||||
bool second_accesses_memory = isLoadInstr(second) || isStoreInstr(second);
|
const InstrInfo& info_second = getInstrInfo(second);
|
||||||
|
|
||||||
if (!first_accesses_memory || !second_accesses_memory) {
|
if (!info_first.has_memory_access || !info_second.has_memory_access) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果至少有一个是存储指令,需要检查别名
|
// 如果至少有一个是存储指令,需要检查别名
|
||||||
if (isStoreInstr(first) || isStoreInstr(second)) {
|
if (info_first.is_store || info_second.is_store) {
|
||||||
MemoryLocation loc1 = getMemoryLocation(first);
|
return mayAlias(info_first.mem_location, info_second.mem_location);
|
||||||
MemoryLocation loc2 = getMemoryLocation(second);
|
|
||||||
return mayAlias(loc1, loc2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // 两个加载指令之间没有依赖
|
return false; // 两个加载指令之间没有依赖
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查两个指令之间是否存在控制依赖
|
// 检查两个指令之间是否存在控制依赖 - 优化版本
|
||||||
static bool hasControlDependency(MachineInstr *first, MachineInstr *second) {
|
static bool hasControlDependency(MachineInstr *first, MachineInstr *second) {
|
||||||
|
const InstrInfo& info_first = getInstrInfo(first);
|
||||||
|
const InstrInfo& info_second = getInstrInfo(second);
|
||||||
|
|
||||||
// 终结指令与任何其他指令都有控制依赖
|
// 终结指令与任何其他指令都有控制依赖
|
||||||
if (isTerminatorInstr(first)) {
|
if (info_first.is_terminator) {
|
||||||
return true; // first是终结指令,second不能移动到first之前
|
return true; // first是终结指令,second不能移动到first之前
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTerminatorInstr(second)) {
|
if (info_second.is_terminator) {
|
||||||
return false; // second是终结指令,可以保持在后面
|
return false; // second是终结指令,可以保持在后面
|
||||||
}
|
}
|
||||||
|
|
||||||
// CALL指令具有控制副作用,但可以参与有限的调度
|
// CALL指令具有控制副作用,但可以参与有限的调度
|
||||||
if (isCallInstr(first) || isCallInstr(second)) {
|
if (info_first.is_call || info_second.is_call) {
|
||||||
// CALL指令之间保持顺序
|
// CALL指令之间保持顺序
|
||||||
if (isCallInstr(first) && isCallInstr(second)) {
|
if (info_first.is_call && info_second.is_call) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// 其他情况允许调度(通过数据依赖控制)
|
// 其他情况允许调度(通过数据依赖控制)
|
||||||
@@ -287,7 +326,7 @@ static bool hasControlDependency(MachineInstr *first, MachineInstr *second) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 综合检查两个指令是否可以交换
|
// 综合检查两个指令是否可以交换 - 优化版本
|
||||||
static bool canSwapInstructions(MachineInstr *first, MachineInstr *second) {
|
static bool canSwapInstructions(MachineInstr *first, MachineInstr *second) {
|
||||||
// 检查所有类型的依赖
|
// 检查所有类型的依赖
|
||||||
if (hasDataDependency(first, second) || hasDataDependency(second, first)) {
|
if (hasDataDependency(first, second) || hasDataDependency(second, first)) {
|
||||||
@@ -306,15 +345,17 @@ static bool canSwapInstructions(MachineInstr *first, MachineInstr *second) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 找到基本块中的调度边界
|
// 找到基本块中的调度边界 - 优化版本
|
||||||
static std::vector<size_t>
|
static std::vector<size_t>
|
||||||
findSchedulingBoundaries(const std::vector<MachineInstr *> &instrs) {
|
findSchedulingBoundaries(const std::vector<MachineInstr *> &instrs) {
|
||||||
std::vector<size_t> boundaries;
|
std::vector<size_t> boundaries;
|
||||||
|
boundaries.reserve(instrs.size() / 10); // 预估边界数量
|
||||||
boundaries.push_back(0); // 起始边界
|
boundaries.push_back(0); // 起始边界
|
||||||
|
|
||||||
for (size_t i = 0; i < instrs.size(); i++) {
|
for (size_t i = 0; i < instrs.size(); i++) {
|
||||||
|
const InstrInfo& info = getInstrInfo(instrs[i]);
|
||||||
// 终结指令前后都是边界
|
// 终结指令前后都是边界
|
||||||
if (isTerminatorInstr(instrs[i])) {
|
if (info.is_terminator) {
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
boundaries.push_back(i);
|
boundaries.push_back(i);
|
||||||
if (i + 1 < instrs.size())
|
if (i + 1 < instrs.size())
|
||||||
@@ -333,7 +374,7 @@ findSchedulingBoundaries(const std::vector<MachineInstr *> &instrs) {
|
|||||||
return boundaries;
|
return boundaries;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在单个调度区域内进行指令调度
|
// 在单个调度区域内进行指令调度 - 优化版本
|
||||||
static void scheduleRegion(std::vector<MachineInstr *> &instrs, size_t start,
|
static void scheduleRegion(std::vector<MachineInstr *> &instrs, size_t start,
|
||||||
size_t end) {
|
size_t end) {
|
||||||
if (end - start <= 1) {
|
if (end - start <= 1) {
|
||||||
@@ -347,7 +388,8 @@ static void scheduleRegion(std::vector<MachineInstr *> &instrs, size_t start,
|
|||||||
|
|
||||||
// 简单的调度算法:只尝试将加载指令尽可能前移
|
// 简单的调度算法:只尝试将加载指令尽可能前移
|
||||||
for (size_t i = start + 1; i < end; i++) {
|
for (size_t i = start + 1; i < end; i++) {
|
||||||
if (isLoadInstr(instrs[i])) {
|
const InstrInfo& info = getInstrInfo(instrs[i]);
|
||||||
|
if (info.is_load) {
|
||||||
// 尝试将加载指令向前移动
|
// 尝试将加载指令向前移动
|
||||||
for (size_t j = i; j > start; j--) {
|
for (size_t j = i; j > start; j--) {
|
||||||
// 检查是否可以与前一条指令交换
|
// 检查是否可以与前一条指令交换
|
||||||
@@ -369,12 +411,21 @@ static void scheduleBlock(MachineBasicBlock *mbb) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理缓存,避免无效指针
|
||||||
|
instr_info_cache.clear();
|
||||||
|
|
||||||
// 构建指令列表
|
// 构建指令列表
|
||||||
std::vector<MachineInstr *> instr_list;
|
std::vector<MachineInstr *> instr_list;
|
||||||
|
instr_list.reserve(instructions.size()); // 预分配容量
|
||||||
for (auto &instr : instructions) {
|
for (auto &instr : instructions) {
|
||||||
instr_list.push_back(instr.get());
|
instr_list.push_back(instr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预计算所有指令信息
|
||||||
|
for (auto* instr : instr_list) {
|
||||||
|
getInstrInfo(instr);
|
||||||
|
}
|
||||||
|
|
||||||
// 找到调度边界
|
// 找到调度边界
|
||||||
std::vector<size_t> boundaries = findSchedulingBoundaries(instr_list);
|
std::vector<size_t> boundaries = findSchedulingBoundaries(instr_list);
|
||||||
|
|
||||||
@@ -386,12 +437,14 @@ static void scheduleBlock(MachineBasicBlock *mbb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 重建指令序列
|
// 重建指令序列
|
||||||
std::map<MachineInstr *, std::unique_ptr<MachineInstr>> instr_map;
|
std::unordered_map<MachineInstr *, std::unique_ptr<MachineInstr>> instr_map;
|
||||||
|
instr_map.reserve(instructions.size()); // 预分配容量
|
||||||
for (auto &instr : instructions) {
|
for (auto &instr : instructions) {
|
||||||
instr_map[instr.get()] = std::move(instr);
|
instr_map[instr.get()] = std::move(instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
instructions.clear();
|
instructions.clear();
|
||||||
|
instructions.reserve(instr_list.size()); // 预分配容量
|
||||||
for (auto *instr : instr_list) {
|
for (auto *instr : instr_list) {
|
||||||
instructions.push_back(std::move(instr_map[instr]));
|
instructions.push_back(std::move(instr_map[instr]));
|
||||||
}
|
}
|
||||||
@@ -405,6 +458,9 @@ void PreRA_Scheduler::runOnMachineFunction(MachineFunction *mfunc) {
|
|||||||
for (auto &mbb : mfunc->getBlocks()) {
|
for (auto &mbb : mfunc->getBlocks()) {
|
||||||
scheduleBlock(mbb.get());
|
scheduleBlock(mbb.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理全局缓存
|
||||||
|
instr_info_cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
@@ -26,7 +26,6 @@ std::string RISCv64CodeGen::module_gen() {
|
|||||||
|
|
||||||
// 判断是否为大型零初始化数组,以便放入.bss段
|
// 判断是否为大型零初始化数组,以便放入.bss段
|
||||||
bool is_large_zero_array = false;
|
bool is_large_zero_array = false;
|
||||||
// 规则:初始化列表只有一项,且该项是值为0的整数,且数量大于一个阈值(例如16)
|
|
||||||
if (init_values.getValues().size() == 1) {
|
if (init_values.getValues().size() == 1) {
|
||||||
if (auto const_val = dynamic_cast<ConstantValue*>(init_values.getValues()[0])) {
|
if (auto const_val = dynamic_cast<ConstantValue*>(init_values.getValues()[0])) {
|
||||||
if (const_val->isInt() && const_val->getInt() == 0 && init_values.getNumbers()[0] > 16) {
|
if (const_val->isInt() && const_val->getInt() == 0 && init_values.getNumbers()[0] > 16) {
|
||||||
@@ -44,19 +43,16 @@ std::string RISCv64CodeGen::module_gen() {
|
|||||||
|
|
||||||
// --- 步骤2:生成 .bss 段的代码 ---
|
// --- 步骤2:生成 .bss 段的代码 ---
|
||||||
if (!bss_globals.empty()) {
|
if (!bss_globals.empty()) {
|
||||||
ss << ".bss\n"; // 切换到 .bss 段
|
ss << ".bss\n";
|
||||||
for (GlobalValue* global : bss_globals) {
|
for (GlobalValue* global : bss_globals) {
|
||||||
// 获取数组总大小(元素个数 * 元素大小)
|
|
||||||
// 在SysY中,我们假设元素都是4字节(int或float)
|
|
||||||
unsigned count = global->getInitValues().getNumbers()[0];
|
unsigned count = global->getInitValues().getNumbers()[0];
|
||||||
unsigned total_size = count * 4;
|
unsigned total_size = count * 4; // 假设元素都是4字节
|
||||||
|
|
||||||
ss << " .align 3\n"; // 8字节对齐 (2^3)
|
ss << " .align 3\n";
|
||||||
ss << ".globl " << global->getName() << "\n";
|
ss << ".globl " << global->getName() << "\n";
|
||||||
ss << ".type " << global->getName() << ", @object\n";
|
ss << ".type " << global->getName() << ", @object\n";
|
||||||
ss << ".size " << global->getName() << ", " << total_size << "\n";
|
ss << ".size " << global->getName() << ", " << total_size << "\n";
|
||||||
ss << global->getName() << ":\n";
|
ss << global->getName() << ":\n";
|
||||||
// 使用 .space 指令来预留指定大小的零填充空间
|
|
||||||
ss << " .space " << total_size << "\n";
|
ss << " .space " << total_size << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,6 +80,30 @@ std::string RISCv64CodeGen::module_gen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// b. [新增] 再处理全局常量 (ConstantVariable)
|
||||||
|
for (const auto& const_ptr : module->getConsts()) {
|
||||||
|
ConstantVariable* cnst = const_ptr.get();
|
||||||
|
ss << ".globl " << cnst->getName() << "\n";
|
||||||
|
ss << cnst->getName() << ":\n";
|
||||||
|
const auto& init_values = cnst->getInitValues();
|
||||||
|
// 这部分逻辑和处理 GlobalValue 完全相同
|
||||||
|
for (size_t i = 0; i < init_values.getValues().size(); ++i) {
|
||||||
|
auto val = init_values.getValues()[i];
|
||||||
|
auto count = init_values.getNumbers()[i];
|
||||||
|
if (auto constant = dynamic_cast<ConstantValue*>(val)) {
|
||||||
|
for (unsigned j = 0; j < count; ++j) {
|
||||||
|
if (constant->isInt()) {
|
||||||
|
ss << " .word " << constant->getInt() << "\n";
|
||||||
|
} else {
|
||||||
|
float f = constant->getFloat();
|
||||||
|
uint32_t float_bits = *(uint32_t*)&f;
|
||||||
|
ss << " .word " << float_bits << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 处理函数 (.text段) ---
|
// --- 处理函数 (.text段) ---
|
||||||
|
|||||||
@@ -1221,6 +1221,11 @@ void RISCv64ISel::selectNode(DAGNode* node) {
|
|||||||
la_instr->addOperand(std::make_unique<RegOperand>(current_addr_vreg));
|
la_instr->addOperand(std::make_unique<RegOperand>(current_addr_vreg));
|
||||||
la_instr->addOperand(std::make_unique<LabelOperand>(global_base->getName()));
|
la_instr->addOperand(std::make_unique<LabelOperand>(global_base->getName()));
|
||||||
CurMBB->addInstruction(std::move(la_instr));
|
CurMBB->addInstruction(std::move(la_instr));
|
||||||
|
} else if (auto const_global_base = dynamic_cast<ConstantVariable*>(base_ptr_node->value)) {
|
||||||
|
auto la_instr = std::make_unique<MachineInstr>(RVOpcodes::LA);
|
||||||
|
la_instr->addOperand(std::make_unique<RegOperand>(current_addr_vreg));
|
||||||
|
la_instr->addOperand(std::make_unique<LabelOperand>(const_global_base->getName()));
|
||||||
|
CurMBB->addInstruction(std::move(la_instr));
|
||||||
} else {
|
} else {
|
||||||
auto base_vreg = getVReg(base_ptr_node->value);
|
auto base_vreg = getVReg(base_ptr_node->value);
|
||||||
auto mv = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
auto mv = std::make_unique<MachineInstr>(RVOpcodes::MV);
|
||||||
|
|||||||
@@ -652,6 +652,7 @@ Function * CallInst::getCallee() const { return dynamic_cast<Function *>(getOper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取变量指针
|
* 获取变量指针
|
||||||
|
* 如果在当前作用域或父作用域中找到变量,则返回该变量的指针,否则返回nullptr
|
||||||
*/
|
*/
|
||||||
auto SymbolTable::getVariable(const std::string &name) const -> Value * {
|
auto SymbolTable::getVariable(const std::string &name) const -> Value * {
|
||||||
auto node = curNode;
|
auto node = curNode;
|
||||||
@@ -688,7 +689,7 @@ auto SymbolTable::addVariable(const std::string &name, Value *variable) -> Value
|
|||||||
if (global != nullptr) {
|
if (global != nullptr) {
|
||||||
globals.emplace_back(global);
|
globals.emplace_back(global);
|
||||||
} else if (constvar != nullptr) {
|
} else if (constvar != nullptr) {
|
||||||
consts.emplace_back(constvar);
|
globalconsts.emplace_back(constvar);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = variable;
|
result = variable;
|
||||||
@@ -703,7 +704,7 @@ auto SymbolTable::getGlobals() -> std::vector<std::unique_ptr<GlobalValue>> & {
|
|||||||
/**
|
/**
|
||||||
* 获取常量
|
* 获取常量
|
||||||
*/
|
*/
|
||||||
auto SymbolTable::getConsts() const -> const std::vector<std::unique_ptr<ConstantVariable>> & { return consts; }
|
auto SymbolTable::getConsts() const -> const std::vector<std::unique_ptr<ConstantVariable>> & { return globalconsts; }
|
||||||
/**
|
/**
|
||||||
* 进入新的作用域
|
* 进入新的作用域
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user