完善performance的4个测试

毕恩凯 3 weeks ago
parent 4bb7007fd3
commit 408f24c05f

@ -412,6 +412,15 @@ class BasicBlock : public Value {
return ptr;
}
template <typename T, typename... Args>
T* Prepend(Args&&... args) {
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get();
ptr->SetParent(this);
instructions_.insert(instructions_.begin(), std::move(inst));
return ptr;
}
private:
Function* parent_ = nullptr;
std::vector<std::unique_ptr<Instruction>> instructions_;

@ -58,6 +58,8 @@ class IRGenImpl final : public SysYBaseVisitor {
std::shared_ptr<ir::Type> ToIRType(const TypeDesc& ty);
std::shared_ptr<ir::Type> ToIRParamType(const TypeDesc& ty);
ir::Value* DefaultValue(const TypeDesc& ty);
ir::AllocaInst* CreateEntryAlloca(std::shared_ptr<ir::Type> ty,
const std::string& name);
void InitArray(ir::Value* base_ptr, const TypeDesc& ty,
SysYParser::InitValContext* init);
void InitConstArray(ir::Value* base_ptr, const TypeDesc& ty,

@ -13,7 +13,7 @@ mkdir -p "$(dirname \"$RESULT_FILE\")"
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCOMPILER_PARSE_ONLY=OFF
cmake --build build -j "$(nproc)"
bash scripts/test_lab2.sh
CASE_DIR=test/test_case bash scripts/test_lab2.sh
echo "[run_lab2] end: $(date '+%Y-%m-%d %H:%M:%S')"
} 2>&1 | tee "$RESULT_FILE"

@ -65,7 +65,13 @@ echo "cases : $CASE_DIR" | tee -a "$LOG_FILE"
echo "out dir : $OUT_DIR" | tee -a "$LOG_FILE"
echo "[Step 1] single sample check: simple_add.sy" | tee -a "$LOG_FILE"
if "$VERIFY_SCRIPT" "$CASE_DIR/simple_add.sy" "$OUT_DIR" --run >> "$LOG_FILE" 2>&1; then
sample_input="$(find "$CASE_DIR" -type f -name "simple_add.sy" -print -quit)"
if [[ -z "$sample_input" ]]; then
echo "single sample: FAIL (simple_add.sy not found under $CASE_DIR)" | tee -a "$LOG_FILE"
echo "stop here. see log: $LOG_FILE" >&2
exit 1
fi
if "$VERIFY_SCRIPT" "$sample_input" "$OUT_DIR" --run >> "$LOG_FILE" 2>&1; then
echo "single sample: PASS" | tee -a "$LOG_FILE"
else
echo "single sample: FAIL" | tee -a "$LOG_FILE"

@ -108,7 +108,7 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
if (!ty) {
throw std::runtime_error(FormatError("irgen", "变量类型缺失"));
}
auto* slot = builder_.CreateAlloca(ToIRType(*ty), module_.GetContext().NextTemp());
auto* slot = CreateEntryAlloca(ToIRType(*ty), module_.GetContext().NextTemp());
var_storage_[ctx] = slot;
if (ty->dims.empty()) {
@ -181,7 +181,7 @@ std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
if (!ty) {
throw std::runtime_error(FormatError("irgen", "常量类型缺失"));
}
auto* slot = builder_.CreateAlloca(ToIRType(*ty), module_.GetContext().NextTemp());
auto* slot = CreateEntryAlloca(ToIRType(*ty), module_.GetContext().NextTemp());
const_storage_[ctx] = slot;
if (ty->dims.empty()) {

@ -122,54 +122,54 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
for (size_t i = 0; i < args.size() && i < param_tys.size(); ++i) {
auto* arg = args[i];
const auto& pty = param_tys[i];
if (pty->IsPointer() && arg && arg->GetType() && arg->GetType()->IsPointer()) {
bool param_elem_array = pty->GetElementType()->IsArray();
bool arg_elem_array = arg->GetType()->GetElementType()->IsArray();
if (!param_elem_array && arg_elem_array) {
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0),
builder_.CreateConstInt(0)};
args[i] = builder_.CreateGep(arg, std::move(idx),
module_.GetContext().NextTemp());
arg = args[i];
} else if (param_elem_array && arg_elem_array) {
auto* param_elem = pty->GetElementType().get();
auto* arg_elem = arg->GetType()->GetElementType().get();
if (param_elem && arg_elem && arg_elem->IsArray() &&
arg_elem->GetElementType()->Equals(*param_elem)) {
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0)};
if (pty->IsPointer()) {
if (arg && arg->GetType() && arg->GetType()->IsPointer()) {
bool param_elem_array = pty->GetElementType()->IsArray();
bool arg_elem_array = arg->GetType()->GetElementType()->IsArray();
if (!param_elem_array && arg_elem_array) {
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0),
builder_.CreateConstInt(0)};
args[i] = builder_.CreateGep(arg, std::move(idx),
module_.GetContext().NextTemp());
arg = args[i];
} else if (param_elem_array && arg_elem_array) {
auto* param_elem = pty->GetElementType().get();
auto* arg_elem = arg->GetType()->GetElementType().get();
if (param_elem && arg_elem && arg_elem->IsArray() &&
arg_elem->GetElementType()->Equals(*param_elem)) {
std::vector<ir::Value*> idx = {builder_.CreateConstInt(0)};
args[i] = builder_.CreateGep(arg, std::move(idx),
module_.GetContext().NextTemp());
arg = args[i];
}
} else if (param_elem_array && !arg_elem_array) {
if (auto* gep = dynamic_cast<ir::GepInst*>(arg)) {
const auto& idx = gep->GetIndices();
auto is_zero = [](ir::Value* v) {
auto* ci = dynamic_cast<ir::ConstantInt*>(v);
return ci && ci->GetValue() == 0;
};
if (idx.size() == 2 && is_zero(idx[0]) && is_zero(idx[1])) {
auto* base = gep->GetBasePtr();
if (base && base->GetType() && base->GetType()->IsPointer() &&
base->GetType()->GetElementType()->IsArray()) {
args[i] = base;
arg = base;
}
}
}
}
} else if (param_elem_array && !arg_elem_array) {
if (auto* gep = dynamic_cast<ir::GepInst*>(arg)) {
const auto& idx = gep->GetIndices();
auto is_zero = [](ir::Value* v) {
auto* ci = dynamic_cast<ir::ConstantInt*>(v);
return ci && ci->GetValue() == 0;
};
if (idx.size() == 2 && is_zero(idx[0]) && is_zero(idx[1])) {
auto* base = gep->GetBasePtr();
if (base && base->GetType() && base->GetType()->IsPointer() &&
base->GetType()->GetElementType()->IsArray()) {
} else if (arg && arg->GetType() && arg->GetType()->IsInt32()) {
if (auto* load = dynamic_cast<ir::LoadInst*>(arg)) {
auto* base = load->GetPtr();
if (base && base->GetType() && base->GetType()->IsPointer()) {
auto* elem = base->GetType()->GetElementType().get();
if (elem && elem->IsPointer() &&
elem->GetElementType()->Equals(*pty->GetElementType())) {
args[i] = base;
arg = base;
}
}
} else if (auto* gep = dynamic_cast<ir::GepInst*>(arg)) {
auto* base = gep->GetBasePtr();
if (base && base->GetType() && base->GetType()->IsPointer() &&
base->GetType()->GetElementType()->IsArray()) {
auto* base_elem = base->GetType()->GetElementType().get();
auto* param_elem = pty->GetElementType().get();
if (base_elem && base_elem->IsArray() && param_elem &&
base_elem->GetElementType()->Equals(*param_elem)) {
std::vector<ir::Value*> idx2 = {builder_.CreateConstInt(0)};
args[i] = builder_.CreateGep(base, std::move(idx2),
module_.GetContext().NextTemp());
arg = args[i];
}
}
}
}
}
@ -329,8 +329,11 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
throw std::runtime_error(FormatError("irgen", "无法解析左值类型"));
}
bool as_rvalue = true;
if (!ty->dims.empty() && ctx->LBRACK().empty()) {
as_rvalue = false;
if (!ty->dims.empty()) {
const size_t index_count = ctx->exp().size();
if (index_count == 0 || index_count < ty->dims.size()) {
as_rvalue = false;
}
}
return static_cast<ir::Value*>(LoadIfNeeded(addr, *ty, as_rvalue));
}
@ -648,6 +651,18 @@ ir::Value* IRGenImpl::DefaultValue(const TypeDesc& ty) {
return builder_.CreateConstInt(0);
}
ir::AllocaInst* IRGenImpl::CreateEntryAlloca(std::shared_ptr<ir::Type> ty,
const std::string& name) {
if (!func_) {
throw std::runtime_error(FormatError("irgen", "CreateEntryAlloca 缺少函数"));
}
auto* entry = func_->GetEntry();
if (!entry) {
throw std::runtime_error(FormatError("irgen", "CreateEntryAlloca 缺少入口块"));
}
return entry->Prepend<ir::AllocaInst>(std::move(ty), name);
}
size_t IRGenImpl::ArrayStride(const TypeDesc& ty, size_t dim) const {
size_t stride = 1;
for (size_t i = dim + 1; i < ty.dims.size(); ++i) {
@ -749,10 +764,14 @@ void IRGenImpl::InitArray(ir::Value* base_ptr, const TypeDesc& ty,
ir::Value* addr = builder_.CreateGep(base_ptr, std::move(indices),
module_.GetContext().NextTemp());
ir::Value* value = values[idx];
if (ty.base == BaseTypeKind::Float && (value->IsInt1() || value->IsInt32())) {
value = CastToFloat(value);
if (ty.base == BaseTypeKind::Float) {
if (value->IsInt1() || value->IsInt32()) {
value = CastToFloat(value->IsInt1() ? CastToInt(value) : value);
}
} else if (ty.base == BaseTypeKind::Int && value->IsFloat()) {
value = CastToInt(value);
} else if (ty.base == BaseTypeKind::Int && value->IsInt1()) {
value = CastToInt(value);
}
builder_.CreateStore(value, addr);
}
@ -777,10 +796,14 @@ void IRGenImpl::InitConstArray(ir::Value* base_ptr, const TypeDesc& ty,
ir::Value* addr = builder_.CreateGep(base_ptr, std::move(indices),
module_.GetContext().NextTemp());
ir::Value* value = values[idx];
if (ty.base == BaseTypeKind::Float && (value->IsInt1() || value->IsInt32())) {
value = CastToFloat(value);
if (ty.base == BaseTypeKind::Float) {
if (value->IsInt1() || value->IsInt32()) {
value = CastToFloat(value->IsInt1() ? CastToInt(value) : value);
}
} else if (ty.base == BaseTypeKind::Int && value->IsFloat()) {
value = CastToInt(value);
} else if (ty.base == BaseTypeKind::Int && value->IsInt1()) {
value = CastToInt(value);
}
builder_.CreateStore(value, addr);
}

@ -62,6 +62,8 @@ std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
declare_builtin("putfloat", ir::Type::GetVoidType(), {f32});
declare_builtin("putfarray", ir::Type::GetVoidType(),
{i32, ir::Type::GetPointerType(f32)});
declare_builtin("starttime", ir::Type::GetVoidType(), {});
declare_builtin("stoptime", ir::Type::GetVoidType(), {});
for (auto* funcDef : ctx->funcDef()) {
if (funcDef) funcDef->accept(this);
@ -98,8 +100,8 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
if (!pty) {
throw std::runtime_error(FormatError("irgen", "缺少参数类型"));
}
auto slot = builder_.CreateAlloca(ToIRParamType(*pty),
module_.GetContext().NextTemp());
auto slot = CreateEntryAlloca(ToIRParamType(*pty),
module_.GetContext().NextTemp());
builder_.CreateStore(arg, slot);
param_storage_[param_ctx] = slot;
}

@ -68,10 +68,18 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
if (!ty) {
throw std::runtime_error(FormatError("irgen", "无法解析赋值类型"));
}
if (ty->base == BaseTypeKind::Float && val->IsInt32()) {
val = CastToFloat(val);
} else if (ty->base == BaseTypeKind::Int && val->IsFloat()) {
val = CastToInt(val);
if (ty->base == BaseTypeKind::Float) {
if (val->IsInt1()) {
val = CastToFloat(CastToInt(val));
} else if (val->IsInt32()) {
val = CastToFloat(val);
}
} else if (ty->base == BaseTypeKind::Int) {
if (val->IsFloat()) {
val = CastToInt(val);
} else if (val->IsInt1()) {
val = CastToInt(val);
}
}
builder_.CreateStore(val, addr);
return BlockFlow::Continue;

@ -495,7 +495,8 @@ class SemaVisitor final : public SysYBaseVisitor {
std::unordered_map<std::string, SysYParser::FuncDefContext*> func_table_;
const std::unordered_set<std::string> builtin_funcs_ = {
"getint", "getch", "getarray", "putint", "putch", "putarray",
"getfloat", "getfarray", "putfloat", "putfarray"};
"getfloat", "getfarray", "putfloat", "putfarray", "starttime",
"stoptime"};
BaseTypeKind current_ret_ = BaseTypeKind::Void;
bool seen_return_ = false;
int loop_depth_ = 0;

@ -22,10 +22,11 @@ void putint(int x) { printf("%d", x); }
void putch(int x) { putchar(x); }
void putarray(int n, int a[]) {
printf("%d", n);
printf("%d:", n);
for (int i = 0; i < n; ++i) {
printf(" %d", a[i]);
}
printf("\n");
}
float getfloat() {
@ -50,5 +51,11 @@ void putfarray(int n, float a[]) {
for (int i = 0; i < n; ++i) {
printf(" %a", a[i]);
}
printf("\n");
}
// Performance timing hooks (no-op stubs for correctness testing).
void starttime() {}
void stoptime() {}

Loading…
Cancel
Save