forked from NUDT-compiler/nudt-compiler-cpp
完成lab4 #9
Merged
ptabmhn4l
merged 6 commits from ptabmhn4l/nudt-compiler-cpp:develop into develop 1 week ago
@ -0,0 +1,3 @@
|
||||
bash scripts/run_ir_test.sh --run # 优化模式,计时
|
||||
bash scripts/run_ir_test.sh --run --O0 # 无优化,计时
|
||||
bash scripts/bench_ir.sh # 同时对比 O0 vs O1
|
||||
@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env bash
|
||||
# 优化效果对比:测量 O0 vs O1 的编译时间和运行时间
|
||||
# 用法: bash scripts/bench_ir.sh [--test-dir=<dir>] [--result-dir=<dir>]
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
PROJECT_ROOT=$(cd "$(dirname "$0")/.." ; pwd)
|
||||
TEST_CASE_DIR="${PROJECT_ROOT}/test/test_case"
|
||||
RESULT_DIR="${PROJECT_ROOT}/test/test_result/bench"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--test-dir=*) TEST_CASE_DIR="${1#*=}" ;;
|
||||
--result-dir=*) RESULT_DIR="${1#*=}" ;;
|
||||
*) echo "未知参数: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
compiler="${PROJECT_ROOT}/build/bin/compiler"
|
||||
[[ -x "$compiler" ]] || { echo "错误:未找到编译器 $compiler" >&2; exit 1; }
|
||||
command -v llc >/dev/null 2>&1 || { echo "错误:未找到 llc" >&2; exit 1; }
|
||||
command -v clang >/dev/null 2>&1 || { echo "错误:未找到 clang" >&2; exit 1; }
|
||||
|
||||
mkdir -p "$RESULT_DIR"
|
||||
|
||||
# 时间测量:使用 date +%s.%N
|
||||
now() { date +%s.%N; }
|
||||
elapsed() { python3 -c "print(f'{float($2)-float($1):.4f}')" 2>/dev/null || awk "BEGIN{printf \"%.4f\\n\",$2-$1}"; }
|
||||
|
||||
summary_file="${RESULT_DIR}/summary.csv"
|
||||
echo "test,opt,compile_s,exec_s,compile+exec_s" > "$summary_file"
|
||||
|
||||
total=0
|
||||
o0_ct_total=0; o1_ct_total=0
|
||||
o0_et_total=0; o1_et_total=0
|
||||
|
||||
echo "=== 优化效果对比 O0 vs O1 ==="
|
||||
echo ""
|
||||
|
||||
while read -r test_file; do
|
||||
full_path=$(readlink -f "$test_file")
|
||||
tcdir=$(readlink -f "$TEST_CASE_DIR")
|
||||
rel="${full_path#$tcdir}"
|
||||
[[ "${rel:0:1}" != "/" ]] && rel="/$rel"
|
||||
|
||||
base=$(basename "$test_file")
|
||||
stem="${base%.sy}"
|
||||
idir=$(dirname "$test_file")
|
||||
stdin="${idir}/${stem}.in"
|
||||
expected="${idir}/${stem}.out"
|
||||
|
||||
total=$((total+1))
|
||||
printf "[%4d] %s" "$total" "$rel"
|
||||
|
||||
o0_ll="${RESULT_DIR}/O0/${rel%.sy}.ll"
|
||||
o1_ll="${RESULT_DIR}/O1/${rel%.sy}.ll"
|
||||
mkdir -p "$(dirname "$o0_ll")" "$(dirname "$o1_ll")"
|
||||
|
||||
# --- 编译 O0 ---
|
||||
t1=$(now)
|
||||
"$compiler" "$test_file" -IR -o "$o0_ll" 2>/dev/null; rc0=$?
|
||||
t2=$(now)
|
||||
if [[ $rc0 -ne 0 ]]; then
|
||||
echo " | O0编译失败"
|
||||
echo "$stem,O0,-,-,-" >> "$summary_file"
|
||||
echo "$stem,O1,-,-,-" >> "$summary_file"
|
||||
continue
|
||||
fi
|
||||
o0_ct=$(elapsed "$t1" "$t2")
|
||||
|
||||
# --- 编译 O1 ---
|
||||
t1=$(now)
|
||||
"$compiler" "$test_file" -IR -o "$o1_ll" -O1 2>/dev/null; rc1=$?
|
||||
t2=$(now)
|
||||
if [[ $rc1 -ne 0 ]]; then
|
||||
echo " | O1编译失败"
|
||||
echo "$stem,O0,$o0_ct,-,-" >> "$summary_file"
|
||||
echo "$stem,O1,-,-,-" >> "$summary_file"
|
||||
continue
|
||||
fi
|
||||
o1_ct=$(elapsed "$t1" "$t2")
|
||||
|
||||
# --- llc + clang O0 ---
|
||||
o0_obj="${RESULT_DIR}/O0/${stem}.o"
|
||||
o1_obj="${RESULT_DIR}/O1/${stem}.o"
|
||||
o0_exe="${RESULT_DIR}/O0/${stem}.exe"
|
||||
o1_exe="${RESULT_DIR}/O1/${stem}.exe"
|
||||
|
||||
llc -filetype=obj "$o0_ll" -o "$o0_obj" 2>/dev/null
|
||||
llc -filetype=obj "$o1_ll" -o "$o1_obj" 2>/dev/null
|
||||
clang "$o0_obj" "${PROJECT_ROOT}/sylib/sylib.c" -o "$o0_exe" -lm 2>/dev/null
|
||||
clang "$o1_obj" "${PROJECT_ROOT}/sylib/sylib.c" -o "$o1_exe" -lm 2>/dev/null
|
||||
|
||||
# --- 运行 O0 ---
|
||||
t1=$(now)
|
||||
sr0=0
|
||||
if [[ -f "$stdin" ]]; then
|
||||
(ulimit -s unlimited; "$o0_exe" < "$stdin") > /dev/null 2>&1 || sr0=$?
|
||||
else
|
||||
(ulimit -s unlimited; "$o0_exe") > /dev/null 2>&1 || sr0=$?
|
||||
fi
|
||||
t2=$(now)
|
||||
o0_et=$(elapsed "$t1" "$t2")
|
||||
|
||||
# --- 运行 O1 ---
|
||||
t1=$(now)
|
||||
sr1=0
|
||||
if [[ -f "$stdin" ]]; then
|
||||
(ulimit -s unlimited; "$o1_exe" < "$stdin") > /dev/null 2>&1 || sr1=$?
|
||||
else
|
||||
(ulimit -s unlimited; "$o1_exe") > /dev/null 2>&1 || sr1=$?
|
||||
fi
|
||||
t2=$(now)
|
||||
o1_et=$(elapsed "$t1" "$t2")
|
||||
|
||||
# 验证一致性
|
||||
flag=""
|
||||
if [[ $sr0 -ne $sr1 ]]; then
|
||||
flag=" EXIT:O0=$sr0 O1=$sr1"
|
||||
fi
|
||||
|
||||
# 累计 & 比率
|
||||
o0_ct_total=$(awk "BEGIN{printf \"%.4f\",$o0_ct_total+$o0_ct}")
|
||||
o1_ct_total=$(awk "BEGIN{printf \"%.4f\",$o1_ct_total+$o1_ct}")
|
||||
o0_et_total=$(awk "BEGIN{printf \"%.4f\",$o0_et_total+$o0_et}")
|
||||
o1_et_total=$(awk "BEGIN{printf \"%.4f\",$o1_et_total+$o1_et}")
|
||||
|
||||
cspd=$(awk "BEGIN{if($o1_ct>0)printf \"%.1fx\",$o0_ct/$o1_ct; else print \"-\"}")
|
||||
espd=$(awk "BEGIN{if($o1_et>0)printf \"%.1fx\",$o0_et/$o1_et; else print \"-\"}")
|
||||
|
||||
printf " | 编译 O0:%.4fs O1:%.4fs(%s) 运行 O0:%.4fs O1:%.4fs(%s)%s\n" \
|
||||
"$o0_ct" "$o1_ct" "$cspd" "$o0_et" "$o1_et" "$espd" "$flag"
|
||||
|
||||
echo "$stem,O0,$o0_ct,$o0_et,$(awk "BEGIN{printf \"%.4f\",$o0_ct+$o0_et}")" >> "$summary_file"
|
||||
echo "$stem,O1,$o1_ct,$o1_et,$(awk "BEGIN{printf \"%.4f\",$o1_ct+$o1_et}")" >> "$summary_file"
|
||||
|
||||
done < <(find "$TEST_CASE_DIR" -name "*.sy" | sort)
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo "总用例: $total"
|
||||
echo "O0 编译总耗时: ${o0_ct_total}s"
|
||||
echo "O1 编译总耗时: ${o1_ct_total}s"
|
||||
echo "O0 运行总耗时: ${o0_et_total}s"
|
||||
echo "O1 运行总耗时: ${o1_et_total}s"
|
||||
echo "CSV: $summary_file"
|
||||
@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
def read_file(filepath):
|
||||
"""读取文件内容,返回行列表"""
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
return f.readlines()
|
||||
except FileNotFoundError:
|
||||
print(f"错误:文件 '{filepath}' 不存在")
|
||||
sys.exit(1)
|
||||
|
||||
def get_context(line, pos, context_len=10):
|
||||
"""获取字符上下文"""
|
||||
start = max(0, pos - context_len)
|
||||
end = min(len(line), pos + context_len + 1)
|
||||
prefix = "..." if start > 0 else ""
|
||||
suffix = "..." if end < len(line) else ""
|
||||
return prefix + line[start:end] + suffix
|
||||
|
||||
def compare_files(file1, file2):
|
||||
"""比较两个文件,输出详细差异"""
|
||||
lines1 = read_file(file1)
|
||||
lines2 = read_file(file2)
|
||||
|
||||
print(f"比较文件: {file1} vs {file2}")
|
||||
print("=" * 80)
|
||||
|
||||
max_lines = max(len(lines1), len(lines2))
|
||||
differences = 0
|
||||
|
||||
for line_num in range(max_lines):
|
||||
line1 = lines1[line_num] if line_num < len(lines1) else None
|
||||
line2 = lines2[line_num] if line_num < len(lines2) else None
|
||||
|
||||
if line1 is None:
|
||||
print(f"\n[新增行] 第 {line_num + 1} 行")
|
||||
print(f" + {repr(line2)}")
|
||||
differences += 1
|
||||
continue
|
||||
|
||||
if line2 is None:
|
||||
print(f"\n[删除行] 第 {line_num + 1} 行")
|
||||
print(f" - {repr(line1)}")
|
||||
differences += 1
|
||||
continue
|
||||
|
||||
if line1 == line2:
|
||||
continue
|
||||
|
||||
# 行内容不同,逐字符比较
|
||||
print(f"\n[差异行] 第 {line_num + 1} 行")
|
||||
|
||||
max_chars = max(len(line1), len(line2))
|
||||
for char_pos in range(max_chars):
|
||||
char1 = line1[char_pos] if char_pos < len(line1) else None
|
||||
char2 = line2[char_pos] if char_pos < len(line2) else None
|
||||
|
||||
if char1 == char2:
|
||||
continue
|
||||
|
||||
# 找到差异字符
|
||||
context1 = get_context(line1, char_pos) if line1 else ""
|
||||
context2 = get_context(line2, char_pos) if line2 else ""
|
||||
|
||||
print(f" 字符位置 {char_pos + 1}:")
|
||||
if char1 is not None:
|
||||
print(f" - {repr(char1)} | 上下文: {repr(context1)}")
|
||||
else:
|
||||
print(f" - (缺失)")
|
||||
if char2 is not None:
|
||||
print(f" + {repr(char2)} | 上下文: {repr(context2)}")
|
||||
else:
|
||||
print(f" + (缺失)")
|
||||
differences += 1
|
||||
|
||||
# 跳过一些连续差异,避免输出过多
|
||||
while char_pos + 1 < max_chars:
|
||||
next_char1 = line1[char_pos + 1] if char_pos + 1 < len(line1) else None
|
||||
next_char2 = line2[char_pos + 1] if char_pos + 1 < len(line2) else None
|
||||
if next_char1 != next_char2:
|
||||
char_pos += 1
|
||||
else:
|
||||
break
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print(f"比较完成,共发现 {differences} 处差异")
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print("用法: python diff.py <文件1> <文件2>")
|
||||
sys.exit(1)
|
||||
|
||||
file1 = sys.argv[1]
|
||||
file2 = sys.argv[2]
|
||||
|
||||
compare_files(file1, file2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,4 +1,205 @@
|
||||
// 支配树分析:
|
||||
// - 构建/查询 Dominator Tree 及相关关系
|
||||
// - 为 mem2reg、CFG 优化与循环分析提供基础能力
|
||||
// - 使用 Cooper-Harvey-Kennedy 算法,近线性时间复杂度
|
||||
|
||||
#include "ir/IR.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace ir {
|
||||
|
||||
void DominatorTree::Compute(Function& func) {
|
||||
func.RebuildCFG();
|
||||
|
||||
// Build block list and reverse postorder (RPO)
|
||||
std::vector<BasicBlock*> blocks;
|
||||
std::unordered_map<BasicBlock*, int> rpo;
|
||||
{
|
||||
std::vector<BasicBlock*> rpo_vec;
|
||||
std::unordered_set<BasicBlock*> visited;
|
||||
std::function<void(BasicBlock*)> dfs = [&](BasicBlock* bb) {
|
||||
if (!bb || visited.count(bb)) return;
|
||||
visited.insert(bb);
|
||||
for (auto* succ : bb->GetSuccessors()) {
|
||||
dfs(succ);
|
||||
}
|
||||
rpo_vec.push_back(bb);
|
||||
};
|
||||
dfs(func.GetEntry());
|
||||
// Reverse to get RPO (postorder reversed)
|
||||
std::reverse(rpo_vec.begin(), rpo_vec.end());
|
||||
blocks = rpo_vec;
|
||||
for (int i = 0; i < (int)blocks.size(); ++i) {
|
||||
rpo[blocks[i]] = i;
|
||||
}
|
||||
}
|
||||
if (blocks.empty()) return;
|
||||
int n = (int)blocks.size();
|
||||
|
||||
auto* entry = func.GetEntry();
|
||||
if (!entry) return;
|
||||
|
||||
// ─── 1. CHK algorithm for immediate dominators ─────────────────────────
|
||||
idom_.clear();
|
||||
idom_[entry] = entry; // entry is its own dominator
|
||||
|
||||
// Intersect: find common ancestor of b1 and b2 walking up the dom tree
|
||||
// Uses RPO number: a dominator always has lower RPO number
|
||||
auto intersect = [&](BasicBlock* b1, BasicBlock* b2) -> BasicBlock* {
|
||||
auto i1 = rpo.find(b1), i2 = rpo.find(b2);
|
||||
if (i1 == rpo.end() || i2 == rpo.end()) return entry;
|
||||
int r1 = i1->second, r2 = i2->second;
|
||||
while (b1 != b2) {
|
||||
while (r1 > r2) {
|
||||
auto it = idom_.find(b1);
|
||||
if (it == idom_.end() || it->second == b1) return b1;
|
||||
b1 = it->second;
|
||||
r1 = rpo[b1];
|
||||
}
|
||||
while (r2 > r1) {
|
||||
auto it = idom_.find(b2);
|
||||
if (it == idom_.end() || it->second == b2) return b2;
|
||||
b2 = it->second;
|
||||
r2 = rpo[b2];
|
||||
}
|
||||
}
|
||||
return b1;
|
||||
};
|
||||
|
||||
bool changed = true;
|
||||
while (changed) {
|
||||
changed = false;
|
||||
// Process in RPO (skip entry which is first in RPO)
|
||||
for (int i = 1; i < n; ++i) {
|
||||
auto* bb = blocks[i];
|
||||
// Find first predecessor with defined IDOM
|
||||
BasicBlock* new_idom = nullptr;
|
||||
for (auto* pred : bb->GetPredecessors()) {
|
||||
if (idom_.count(pred) && pred != bb) {
|
||||
new_idom = pred;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!new_idom) continue;
|
||||
|
||||
// Intersect with remaining predecessors
|
||||
for (auto* pred : bb->GetPredecessors()) {
|
||||
if (pred == new_idom || pred == bb) continue;
|
||||
if (idom_.count(pred)) {
|
||||
new_idom = intersect(pred, new_idom);
|
||||
}
|
||||
}
|
||||
|
||||
auto old = idom_.find(bb);
|
||||
if (old == idom_.end() || old->second != new_idom) {
|
||||
idom_[bb] = new_idom;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Entry is its own IDOM, set to nullptr for external queries
|
||||
idom_[entry] = nullptr;
|
||||
|
||||
// Unreached blocks get entry as IDOM
|
||||
for (auto* bb : blocks) {
|
||||
if (!idom_.count(bb)) idom_[bb] = entry;
|
||||
}
|
||||
|
||||
// ─── 2. Build children map and dom levels ──────────────────────────────
|
||||
children_.clear();
|
||||
dom_level_.clear();
|
||||
for (auto& [child, parent] : idom_) {
|
||||
if (parent) children_[parent].push_back(child);
|
||||
}
|
||||
|
||||
// BFS to compute dom levels
|
||||
std::queue<BasicBlock*> q;
|
||||
dom_level_[entry] = 0;
|
||||
q.push(entry);
|
||||
while (!q.empty()) {
|
||||
auto* cur = q.front();
|
||||
q.pop();
|
||||
size_t cur_level = dom_level_[cur];
|
||||
auto it = children_.find(cur);
|
||||
if (it != children_.end()) {
|
||||
for (auto* child : it->second) {
|
||||
dom_level_[child] = cur_level + 1;
|
||||
q.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─── 3. Compute dominance frontier ─────────────────────────────────────
|
||||
df_.clear();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
auto* b = blocks[i];
|
||||
if (b->GetPredecessors().size() < 2) continue;
|
||||
for (auto* p : b->GetPredecessors()) {
|
||||
auto* runner = p;
|
||||
auto* b_idom = GetIDom(b);
|
||||
while (runner != b_idom) {
|
||||
if (!runner) break;
|
||||
df_[runner].push_back(b);
|
||||
runner = GetIDom(runner);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Deduplicate DF entries
|
||||
for (auto& [bb, vec] : df_) {
|
||||
std::sort(vec.begin(), vec.end());
|
||||
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||
}
|
||||
|
||||
// ─── 4. Compute DFS order of dominator tree ────────────────────────────
|
||||
df_order_.clear();
|
||||
visited_.clear();
|
||||
std::function<void(BasicBlock*)> dfs_tree = [&](BasicBlock* bb) {
|
||||
if (!bb || visited_.count(bb)) return;
|
||||
visited_.insert(bb);
|
||||
df_order_.push_back(bb);
|
||||
auto it = children_.find(bb);
|
||||
if (it != children_.end()) {
|
||||
for (auto* child : it->second) {
|
||||
dfs_tree(child);
|
||||
}
|
||||
}
|
||||
};
|
||||
dfs_tree(entry);
|
||||
}
|
||||
|
||||
BasicBlock* DominatorTree::GetIDom(BasicBlock* bb) const {
|
||||
auto it = idom_.find(bb);
|
||||
return (it != idom_.end()) ? it->second : nullptr;
|
||||
}
|
||||
|
||||
const std::vector<BasicBlock*>& DominatorTree::GetChildren(
|
||||
BasicBlock* bb) const {
|
||||
static const std::vector<BasicBlock*> empty;
|
||||
auto it = children_.find(bb);
|
||||
return (it != children_.end()) ? it->second : empty;
|
||||
}
|
||||
|
||||
const std::vector<BasicBlock*>& DominatorTree::GetDominanceFrontier(
|
||||
BasicBlock* bb) const {
|
||||
static const std::vector<BasicBlock*> empty;
|
||||
auto it = df_.find(bb);
|
||||
return (it != df_.end()) ? it->second : empty;
|
||||
}
|
||||
|
||||
bool DominatorTree::Dominates(BasicBlock* a, BasicBlock* b) const {
|
||||
if (a == b) return true;
|
||||
BasicBlock* runner = b;
|
||||
while (runner) {
|
||||
runner = GetIDom(runner);
|
||||
if (runner == a) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ir
|
||||
|
||||
@ -1,4 +1,187 @@
|
||||
// IR 常量折叠:
|
||||
// - 折叠可判定的常量表达式
|
||||
// - 简化常量控制流分支(按实现范围裁剪)
|
||||
// - 简化常量控制流分支
|
||||
|
||||
#include "ir/IR.h"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace ir {
|
||||
|
||||
namespace {
|
||||
|
||||
// 在释放指令前断开其 use-def 链,避免其他值的 uses_ 中有悬空指针
|
||||
static void DetachAndRemove(Instruction* inst) {
|
||||
// 先断开自身对操作数的引用,清除 use-def 链
|
||||
for (size_t i = 0; i < inst->GetNumOperands(); ++i)
|
||||
inst->SetOperand(i, nullptr);
|
||||
// 然后从父块中移除(清除父指针后不会再次尝试访问)
|
||||
if (auto* parent = inst->GetParent()) {
|
||||
parent->RemoveInstruction(inst);
|
||||
}
|
||||
}
|
||||
|
||||
bool FoldICmp(ICmpInst* cmp, Context& ctx) {
|
||||
auto* lhs = dynamic_cast<ConstantInt*>(cmp->GetLhs());
|
||||
auto* rhs = dynamic_cast<ConstantInt*>(cmp->GetRhs());
|
||||
if (!lhs || !rhs) return false;
|
||||
|
||||
int lv = lhs->GetValue(), rv = rhs->GetValue();
|
||||
bool result = false;
|
||||
switch (cmp->GetPredicate()) {
|
||||
case ICmpPredicate::EQ: result = lv == rv; break;
|
||||
case ICmpPredicate::NE: result = lv != rv; break;
|
||||
case ICmpPredicate::SLT: result = lv < rv; break;
|
||||
case ICmpPredicate::SLE: result = lv <= rv; break;
|
||||
case ICmpPredicate::SGT: result = lv > rv; break;
|
||||
case ICmpPredicate::SGE: result = lv >= rv; break;
|
||||
}
|
||||
cmp->ReplaceAllUsesWith(ctx.GetConstInt(result ? 1 : 0));
|
||||
DetachAndRemove(cmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FoldFCmp(FCmpInst* cmp, Context& ctx) {
|
||||
auto* lhs = dynamic_cast<ConstantFloat*>(cmp->GetLhs());
|
||||
auto* rhs = dynamic_cast<ConstantFloat*>(cmp->GetRhs());
|
||||
if (!lhs || !rhs) return false;
|
||||
|
||||
float lv = lhs->GetValue(), rv = rhs->GetValue();
|
||||
bool result = false;
|
||||
switch (cmp->GetPredicate()) {
|
||||
case FCmpPredicate::OEQ: result = lv == rv; break;
|
||||
case FCmpPredicate::ONE: result = lv != rv; break;
|
||||
case FCmpPredicate::OLT: result = lv < rv; break;
|
||||
case FCmpPredicate::OLE: result = lv <= rv; break;
|
||||
case FCmpPredicate::OGT: result = lv > rv; break;
|
||||
case FCmpPredicate::OGE: result = lv >= rv; break;
|
||||
}
|
||||
cmp->ReplaceAllUsesWith(ctx.GetConstInt(result ? 1 : 0));
|
||||
DetachAndRemove(cmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FoldZExt(ZExtInst* zext, Context& ctx) {
|
||||
auto* src = dynamic_cast<ConstantInt*>(zext->GetSrc());
|
||||
if (!src) return false;
|
||||
zext->ReplaceAllUsesWith(ctx.GetConstInt(src->GetValue() != 0 ? 1 : 0));
|
||||
DetachAndRemove(zext);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FoldSIToFP(SIToFPInst* inst, Context& ctx) {
|
||||
auto* src = dynamic_cast<ConstantInt*>(inst->GetSrc());
|
||||
if (!src) return false;
|
||||
inst->ReplaceAllUsesWith(ctx.GetConstFloat(static_cast<float>(src->GetValue())));
|
||||
DetachAndRemove(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FoldFPToSI(FPToSIInst* inst, Context& ctx) {
|
||||
auto* src = dynamic_cast<ConstantFloat*>(inst->GetSrc());
|
||||
if (!src) return false;
|
||||
inst->ReplaceAllUsesWith(ctx.GetConstInt(static_cast<int>(src->GetValue())));
|
||||
DetachAndRemove(inst);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fold constant binary operations (int and float)
|
||||
bool FoldBinaryWithCtx(BinaryInst* bin, Context& ctx) {
|
||||
auto* lhs_c = dynamic_cast<ConstantInt*>(bin->GetLhs());
|
||||
auto* rhs_c = dynamic_cast<ConstantInt*>(bin->GetRhs());
|
||||
auto* lhs_f = dynamic_cast<ConstantFloat*>(bin->GetLhs());
|
||||
auto* rhs_f = dynamic_cast<ConstantFloat*>(bin->GetRhs());
|
||||
|
||||
if (lhs_c && rhs_c) {
|
||||
int lv = lhs_c->GetValue(), rv = rhs_c->GetValue();
|
||||
int result = 0;
|
||||
bool valid = true;
|
||||
switch (bin->GetOpcode()) {
|
||||
case Opcode::Add: result = lv + rv; break;
|
||||
case Opcode::Sub: result = lv - rv; break;
|
||||
case Opcode::Mul: result = lv * rv; break;
|
||||
case Opcode::Div: if (rv != 0) result = lv / rv; else valid = false; break;
|
||||
case Opcode::Mod: if (rv != 0) result = lv % rv; else valid = false; break;
|
||||
default: valid = false; break;
|
||||
}
|
||||
if (valid) {
|
||||
bin->ReplaceAllUsesWith(ctx.GetConstInt(result));
|
||||
DetachAndRemove(bin);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (lhs_f && rhs_f) {
|
||||
float lv = lhs_f->GetValue(), rv = rhs_f->GetValue();
|
||||
float result = 0.0f;
|
||||
bool valid = true;
|
||||
switch (bin->GetOpcode()) {
|
||||
case Opcode::FAdd: result = lv + rv; break;
|
||||
case Opcode::FSub: result = lv - rv; break;
|
||||
case Opcode::FMul: result = lv * rv; break;
|
||||
case Opcode::FDiv: if (rv != 0.0f) result = lv / rv; else valid = false; break;
|
||||
default: valid = false; break;
|
||||
}
|
||||
if (valid) {
|
||||
bin->ReplaceAllUsesWith(ctx.GetConstFloat(result));
|
||||
DetachAndRemove(bin);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool RunConstFold(Function& func, Context& ctx) {
|
||||
bool changed = false;
|
||||
std::unordered_set<void*> removed;
|
||||
|
||||
bool any_changed = true;
|
||||
while (any_changed) {
|
||||
any_changed = false;
|
||||
for (auto& bb : func.GetBlocks()) {
|
||||
// 每轮重新收集(因为指令列表在变化)
|
||||
std::vector<Instruction*> insts;
|
||||
for (auto& inst : bb->GetInstructions())
|
||||
insts.push_back(inst.get());
|
||||
|
||||
for (auto* inst : insts) {
|
||||
if (removed.count(inst)) continue;
|
||||
bool folded = false;
|
||||
switch (inst->GetOpcode()) {
|
||||
case Opcode::Add: case Opcode::Sub: case Opcode::Mul:
|
||||
case Opcode::Div: case Opcode::Mod:
|
||||
case Opcode::FAdd: case Opcode::FSub:
|
||||
case Opcode::FMul: case Opcode::FDiv:
|
||||
folded = FoldBinaryWithCtx(static_cast<BinaryInst*>(inst), ctx);
|
||||
break;
|
||||
case Opcode::ICmp:
|
||||
folded = FoldICmp(static_cast<ICmpInst*>(inst), ctx);
|
||||
break;
|
||||
case Opcode::FCmp:
|
||||
folded = FoldFCmp(static_cast<FCmpInst*>(inst), ctx);
|
||||
break;
|
||||
case Opcode::ZExt:
|
||||
folded = FoldZExt(static_cast<ZExtInst*>(inst), ctx);
|
||||
break;
|
||||
case Opcode::SIToFP:
|
||||
folded = FoldSIToFP(static_cast<SIToFPInst*>(inst), ctx);
|
||||
break;
|
||||
case Opcode::FPToSI:
|
||||
folded = FoldFPToSI(static_cast<FPToSIInst*>(inst), ctx);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (folded) {
|
||||
removed.insert(inst);
|
||||
any_changed = true;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
} // namespace ir
|
||||
|
||||
Binary file not shown.
@ -1,42 +1,83 @@
|
||||
// SysY 运行库实现:
|
||||
// - 按实验/评测规范提供 I/O 等函数实现
|
||||
// - 与编译器生成的目标代码链接,支撑运行时行为
|
||||
|
||||
#include<stdio.h>
|
||||
#include<stdarg.h>
|
||||
#include<sys/time.h>
|
||||
#include"sylib.h"
|
||||
/* Input & output functions */
|
||||
int getint(){int t; scanf("%d",&t); return t; }
|
||||
int getch(){char c; scanf("%c",&c); return (int)c; }
|
||||
float getfloat(){
|
||||
float n;
|
||||
scanf("%a", &n);
|
||||
return n;
|
||||
}
|
||||
|
||||
int getarray(int a[]){
|
||||
int n;
|
||||
scanf("%d",&n);
|
||||
for(int i=0;i<n;i++)scanf("%d",&a[i]);
|
||||
return n;
|
||||
}
|
||||
|
||||
int getfarray(float a[]) {
|
||||
int n;
|
||||
scanf("%d",&n);
|
||||
for(int i=0;i<n;i++)scanf("%d",&a[i]);
|
||||
scanf("%d", &n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
scanf("%a", &a[i]);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
void putint(int a){ printf("%d",a);}
|
||||
void putch(int a){ printf("%c",a); }
|
||||
void putarray(int n,int a[]){
|
||||
printf("%d:",n);
|
||||
for(int i=0;i<n;i++)printf(" %d",a[i]);
|
||||
printf("\n");
|
||||
printf("%d:",n);
|
||||
for(int i=0;i<n;i++)printf(" %d",a[i]);
|
||||
printf("\n");
|
||||
}
|
||||
float getfloat(){ float f; scanf("%f",&f); return f; }
|
||||
void putfloat(float a){ printf("%a",a); }
|
||||
int getfarray(float a[]){
|
||||
int n; scanf("%d",&n);
|
||||
for(int i=0;i<n;i++) scanf("%a",&a[i]);
|
||||
return n;
|
||||
void putfloat(float a) {
|
||||
printf("%a", a);
|
||||
}
|
||||
void putfarray(int n,float a[]){
|
||||
printf("%d:",n);
|
||||
for(int i=0;i<n;i++) printf(" %a",a[i]);
|
||||
void putfarray(int n, float a[]) {
|
||||
printf("%d:", n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
printf(" %a", a[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
static struct timeval _sysy_start, _sysy_end;
|
||||
void starttime(){ gettimeofday(&_sysy_start, NULL); }
|
||||
void stoptime(){
|
||||
gettimeofday(&_sysy_end, NULL);
|
||||
long us = (_sysy_end.tv_sec - _sysy_start.tv_sec) * 1000000L
|
||||
+ (_sysy_end.tv_usec - _sysy_start.tv_usec);
|
||||
fprintf(stderr, "Timer: %ldus\n", us);
|
||||
}
|
||||
|
||||
void putf(char a[], ...) {
|
||||
va_list args;
|
||||
va_start(args, a);
|
||||
vfprintf(stdout, a, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* Timing function implementation */
|
||||
__attribute((constructor)) void before_main(){
|
||||
for(int i=0;i<_SYSY_N;i++)
|
||||
_sysy_h[i] = _sysy_m[i]= _sysy_s[i] = _sysy_us[i] =0;
|
||||
_sysy_idx=1;
|
||||
}
|
||||
__attribute((destructor)) void after_main(){
|
||||
for(int i=1;i<_sysy_idx;i++){
|
||||
fprintf(stderr,"Timer@%04d-%04d: %dH-%dM-%dS-%dus\n",\
|
||||
_sysy_l1[i],_sysy_l2[i],_sysy_h[i],_sysy_m[i],_sysy_s[i],_sysy_us[i]);
|
||||
_sysy_us[0]+= _sysy_us[i];
|
||||
_sysy_s[0] += _sysy_s[i]; _sysy_us[0] %= 1000000;
|
||||
_sysy_m[0] += _sysy_m[i]; _sysy_s[0] %= 60;
|
||||
_sysy_h[0] += _sysy_h[i]; _sysy_m[0] %= 60;
|
||||
}
|
||||
fprintf(stderr,"TOTAL: %dH-%dM-%dS-%dus\n",_sysy_h[0],_sysy_m[0],_sysy_s[0],_sysy_us[0]);
|
||||
}
|
||||
void _sysy_starttime(int lineno){
|
||||
_sysy_l1[_sysy_idx] = lineno;
|
||||
gettimeofday(&_sysy_start,NULL);
|
||||
}
|
||||
void _sysy_stoptime(int lineno){
|
||||
gettimeofday(&_sysy_end,NULL);
|
||||
_sysy_l2[_sysy_idx] = lineno;
|
||||
_sysy_us[_sysy_idx] += 1000000 * ( _sysy_end.tv_sec - _sysy_start.tv_sec ) + _sysy_end.tv_usec - _sysy_start.tv_usec;
|
||||
_sysy_s[_sysy_idx] += _sysy_us[_sysy_idx] / 1000000 ; _sysy_us[_sysy_idx] %= 1000000;
|
||||
_sysy_m[_sysy_idx] += _sysy_s[_sysy_idx] / 60 ; _sysy_s[_sysy_idx] %= 60;
|
||||
_sysy_h[_sysy_idx] += _sysy_m[_sysy_idx] / 60 ; _sysy_m[_sysy_idx] %= 60;
|
||||
_sysy_idx ++;
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
int main() {
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
int c = a + b;
|
||||
return c;
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
// 基础算术运算测试
|
||||
int main() {
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
int c = a + b; // 30
|
||||
int d = c - 5; // 25
|
||||
int e = d * 2; // 50
|
||||
return e;
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
// 除法测试
|
||||
int main() {
|
||||
int a = 100;
|
||||
int b = 4;
|
||||
return a / b; // 25
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
int main() {
|
||||
float a = 10;
|
||||
float b = 3;
|
||||
float c = a + b;
|
||||
return (int)c;
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
const float arr[3] = {1.1, 2.2, 3.3};
|
||||
float carr[3] = {4.4, 5.5, 6.6};
|
||||
|
||||
int main() {
|
||||
float sum = arr[0] + carr[0];
|
||||
return (int)sum; // 5
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
int main() {
|
||||
float a = 5.0;
|
||||
float b = 3.0;
|
||||
int cmp1 = (a > b); // 1
|
||||
int cmp2 = (a < b); // 0
|
||||
int cmp3 = (a == 5.0); // 1
|
||||
return cmp1 + cmp2 + cmp3; // 2
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
int main() {
|
||||
float a = (float)10;
|
||||
float b = (float)3;
|
||||
float c = a / b;
|
||||
int d = c;
|
||||
return d;
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
const float pi = 3.14159;
|
||||
float g = 2.71828;
|
||||
|
||||
int main() {
|
||||
float a = pi;
|
||||
float b = g;
|
||||
float c = a + b;
|
||||
return (int)c; // 5
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
int main() {
|
||||
float a = 10;
|
||||
float b = 3;
|
||||
float c = a * b;
|
||||
return (int)c;
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
int main() {
|
||||
float a = 10.0;
|
||||
float b = 3.0;
|
||||
float add = a + b; // 13
|
||||
float sub = a - b; // 7
|
||||
float mul = a * b; // 30
|
||||
float div = a / b; // 3.333...
|
||||
return (int)(add + sub + mul + (int)div);
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
int main() {
|
||||
int a = 5;
|
||||
int b = 10;
|
||||
int c = a < b;
|
||||
return c;
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
int main() {
|
||||
int a = 5;
|
||||
int b = 10;
|
||||
int c = a < b;
|
||||
return c;
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
int main() {
|
||||
int a = 5;
|
||||
int b = 10;
|
||||
int c = 0;
|
||||
if (a < b) {
|
||||
c = 1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
int main() {
|
||||
int a = 10;
|
||||
int b = 20;
|
||||
int c = 0;
|
||||
|
||||
if (a < b) {
|
||||
c = 100;
|
||||
} else {
|
||||
c = 200;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
// 取模测试
|
||||
int main() {
|
||||
int a = 17;
|
||||
int b = 5;
|
||||
return a % b; // 2
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
// 乘法测试
|
||||
int main() {
|
||||
int a = 5;
|
||||
int b = 10;
|
||||
return a * b; // 50
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
int main() {
|
||||
int a = 5;
|
||||
int b = 10;
|
||||
int c = 15;
|
||||
int result = 0;
|
||||
|
||||
if (a < b) {
|
||||
if (b < c) {
|
||||
result = 100;
|
||||
} else {
|
||||
result = 200;
|
||||
}
|
||||
} else {
|
||||
result = 300;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
int main() {
|
||||
return 42;
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
int main() {
|
||||
int a = 10;
|
||||
int b = 3;
|
||||
return a - b;
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
int main() {
|
||||
float a = 3.14;
|
||||
return a;
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
// 变量读写测试
|
||||
int main() {
|
||||
int x = 42;
|
||||
int y = x;
|
||||
int z = y + 1;
|
||||
return z; // 43
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
int main() {
|
||||
int i = 0;
|
||||
int sum = 0;
|
||||
|
||||
while (i < 10) {
|
||||
sum = sum + i;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
int main() { /* scope test */ putch(97); putch(10); int a = 1, putch = 0; { a = a + 2; int b = a + 3; b = b + 4; putch = putch + a + b; { b = b + 5; int main = b + 6; a = a + main; putch = putch + a + b + main; { b = b + a; int a = main + 7; a = a + 8; putch = putch + a + b + main; { b = b + a; int b = main + 9; a = a + 10; const int a = 11; b = b + 12; putch = putch + a + b + main; { main = main + b; int main = b + 13; main = main + a; putch = putch + a + b + main; } putch = putch - main; } putch = putch - b; } putch = putch - a; } } return putch % 77; }
|
||||
@ -1,5 +0,0 @@
|
||||
int main() {
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
return a + b;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,2 +0,0 @@
|
||||
1691748973
|
||||
0
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,71 +0,0 @@
|
||||
int x;
|
||||
|
||||
const int N = 2010;
|
||||
|
||||
void mv(int n, int A[][N], int b[], int res[]){
|
||||
int x, y;
|
||||
y = 0;
|
||||
x = 11;
|
||||
int i, j;
|
||||
|
||||
i = 0;
|
||||
while(i < n){
|
||||
res[i] = 0;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
while (i < n){
|
||||
j = 0;
|
||||
while (j < n){
|
||||
if (A[i][j] == 0){
|
||||
x = x * b[i] + b[j];
|
||||
y = y - x;
|
||||
}else{
|
||||
res[i] = res[i] + A[i][j] * b[j];
|
||||
}
|
||||
j = j + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int A[N][N];
|
||||
int B[N];
|
||||
int C[N];
|
||||
|
||||
int main(){
|
||||
int n = getint();
|
||||
int i, j;
|
||||
|
||||
i = 0;
|
||||
|
||||
while (i < n){
|
||||
j = 0;
|
||||
while (j < n){
|
||||
A[i][j] = getint();
|
||||
j = j + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < n){
|
||||
B[i] = getint();
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
starttime();
|
||||
|
||||
i = 0;
|
||||
while (i < 50){
|
||||
mv(n, A, B, C);
|
||||
mv(n, A, C, B);
|
||||
i = i + 1;
|
||||
}
|
||||
stoptime();
|
||||
|
||||
putarray(n, C);
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,2 +0,0 @@
|
||||
1576633458
|
||||
0
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,2 +0,0 @@
|
||||
1352004184
|
||||
0
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,51 +0,0 @@
|
||||
50 50 353434
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
.....................#..#.........................
|
||||
.....................#..#.........................
|
||||
...................##.##.##.......................
|
||||
.....................#..#.........................
|
||||
.....................#..#.........................
|
||||
...................##.##.##.......................
|
||||
.....................#..#.........................
|
||||
.....................#..#.........................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
@ -1,51 +0,0 @@
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
......................##..........................
|
||||
.....................####.........................
|
||||
....................#....#........................
|
||||
...................##....##.......................
|
||||
...................##....##.......................
|
||||
....................#....#........................
|
||||
.....................####.........................
|
||||
......................##..........................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
..................................................
|
||||
0
|
||||
@ -1,112 +0,0 @@
|
||||
int sheet1[500][500] = {};
|
||||
int sheet2[500][500] = {};
|
||||
int active = 1;
|
||||
int width;
|
||||
int height;
|
||||
int steps;
|
||||
|
||||
void read_map() {
|
||||
width = getint();
|
||||
height = getint();
|
||||
// width <= 498, height <= 498
|
||||
steps = getint();
|
||||
getch();
|
||||
|
||||
int i = 1;
|
||||
int j = 1;
|
||||
|
||||
while (j <= height) {
|
||||
i = 1;
|
||||
while (i <= width) {
|
||||
int get = getch();
|
||||
if (get == 35) {
|
||||
sheet1[j][i] = 1;
|
||||
} else {
|
||||
sheet1[j][i] = 0;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
// line feed
|
||||
getch();
|
||||
j = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void put_map() {
|
||||
int i = 1;
|
||||
int j = 1;
|
||||
|
||||
while (j <= height) {
|
||||
i = 1;
|
||||
while (i <= width) {
|
||||
if (sheet1[j][i] == 1) {
|
||||
putch(35);
|
||||
} else {
|
||||
putch(46);
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
// line feed
|
||||
putch(10);
|
||||
j = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void swap12() {
|
||||
int i = 1;
|
||||
int j = 1;
|
||||
|
||||
while (j <= height) {
|
||||
i = 1;
|
||||
while (i <= width) {
|
||||
sheet1[j][i] = sheet2[j][i];
|
||||
i = i + 1;
|
||||
}
|
||||
j = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void step(int source[][500], int target[][500]) {
|
||||
int i = 1;
|
||||
int j = 1;
|
||||
|
||||
while (j <= height) {
|
||||
i = 1;
|
||||
while (i <= width) {
|
||||
int alive_count = source[j - 1][i - 1] + source[j - 1][i] +
|
||||
source[j - 1][i + 1] + source[j][i - 1] +
|
||||
source[j][i + 1] + source[j + 1][i - 1] +
|
||||
source[j + 1][i] + source[j + 1][i + 1];
|
||||
if (source[j][i] == 1 && alive_count == 2 ) {
|
||||
target[j][i] = 1;
|
||||
} else if (alive_count == 3) {
|
||||
target[j][i] = 1;
|
||||
} else {
|
||||
target[j][i] = 0;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
j = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
read_map();
|
||||
starttime();
|
||||
while (steps > 0) {
|
||||
if (active == 1) {
|
||||
step(sheet1, sheet2);
|
||||
active = 2;
|
||||
} else {
|
||||
step(sheet2, sheet1);
|
||||
active = 1;
|
||||
}
|
||||
steps = steps - 1;
|
||||
}
|
||||
stoptime();
|
||||
if (active == 2) {
|
||||
swap12();
|
||||
}
|
||||
put_map();
|
||||
return 0;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
50000000
|
||||
@ -1,2 +0,0 @@
|
||||
60255
|
||||
0
|
||||
@ -1 +0,0 @@
|
||||
4096
|
||||
@ -1,49 +0,0 @@
|
||||
|
||||
int COUNT = 500000;
|
||||
|
||||
float loop(float x[], float y[], int length) {
|
||||
int i = 0;
|
||||
float accumulator = 0.0;
|
||||
while (i < length) {
|
||||
accumulator = accumulator + x[i] * y[i];
|
||||
i = i + 1;
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i = 0, j = 0;
|
||||
int len = getint();
|
||||
float x[4096];
|
||||
float y[4096];
|
||||
float total = 0.0;
|
||||
float a = 0.0;
|
||||
float b = 1.0;
|
||||
starttime();
|
||||
while ( i < COUNT) {
|
||||
if (i % 10) {
|
||||
a = 0.0;
|
||||
b = 1.0;
|
||||
} else {
|
||||
a = a + 0.1;
|
||||
b = b + 0.2;
|
||||
}
|
||||
while ( j < len) {
|
||||
x[j] = a + j;
|
||||
y[j] = b + j;
|
||||
j = j + 1;
|
||||
}
|
||||
total = total + loop(x, y, len);
|
||||
i = i + 1;
|
||||
}
|
||||
stoptime();
|
||||
if ((total - 11442437121638400.000000) <=0.000001 || (total - 11442437121638400.000000) >= -0.000001) {
|
||||
putint(0);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
putint(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
1042523985
|
||||
0
|
||||
@ -1,85 +0,0 @@
|
||||
int func(int i, int j) {
|
||||
return ((i+j) * (i+j+1) / 2 + i + 1);
|
||||
}
|
||||
|
||||
float Vectordot(float v[], float u[], int n) {
|
||||
int i = 0;
|
||||
float sum = 0;
|
||||
while (i < n) {
|
||||
sum =sum+ v[i] * u[i];
|
||||
i=i+1;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
void mult1(float v[], float out[],int n) {
|
||||
int i = 0, j = 0;
|
||||
float sum = 0;
|
||||
|
||||
while (i < n) {
|
||||
while (j < n) {
|
||||
sum =sum+ v[j] / func(i,j);
|
||||
j=j+1;
|
||||
}
|
||||
out[i] = sum;
|
||||
i=i+1;
|
||||
}
|
||||
}
|
||||
|
||||
void mult2(float v[], float out[], int n) {
|
||||
int i = 0, j = 0;
|
||||
float sum = 0;
|
||||
|
||||
while (i < n) {
|
||||
while (j < n) {
|
||||
sum =sum+ v[j] / func(j,i);
|
||||
j=j+1;
|
||||
}
|
||||
out[i] = sum;
|
||||
i=i+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mult_combin(float v[], float out[], int n, float tmp[]) {
|
||||
mult1(v, tmp, n);
|
||||
mult2(tmp, out, n);
|
||||
}
|
||||
|
||||
float temp = 1;
|
||||
float my_sqrt(float input) {
|
||||
while (temp - input / temp > 1e-6 || temp - input / temp < -1e-6){
|
||||
temp = (temp+input/temp)/2;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n = 100000;
|
||||
if (n <= 0) {
|
||||
n = 2000;
|
||||
}
|
||||
starttime();
|
||||
float vectorA[100000], vectorB[100000], Vectortmp[100000];
|
||||
|
||||
int i;
|
||||
while(i < n) {
|
||||
vectorA[i] = 1;
|
||||
i=i+1;
|
||||
}
|
||||
i = 0;
|
||||
while(i < 1000) {
|
||||
mult_combin(vectorA, vectorB, n, Vectortmp);
|
||||
mult_combin(vectorB, vectorA, n, Vectortmp);
|
||||
i=i+1;
|
||||
}
|
||||
stoptime();
|
||||
float result = my_sqrt(Vectordot(vectorA,vectorB, n) / Vectordot(vectorB,vectorB,n));
|
||||
if(result - 1.000000 <= 1e-6 && result - 1.000000 >= -1e-6){
|
||||
putint(1);
|
||||
}else{
|
||||
putint(0);
|
||||
}
|
||||
putch(10);
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,3 @@
|
||||
int main(){
|
||||
return 3;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
10
|
||||
@ -0,0 +1,8 @@
|
||||
//test domain of global var define and local define
|
||||
int a = 3;
|
||||
int b = 5;
|
||||
|
||||
int main(){
|
||||
int a = 5;
|
||||
return a + b;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
5
|
||||
@ -0,0 +1,8 @@
|
||||
//test local var define
|
||||
int main(){
|
||||
int a, b0, _c;
|
||||
a = 1;
|
||||
b0 = 2;
|
||||
_c = 3;
|
||||
return b0 + _c;
|
||||
}
|
||||
@ -1,2 +1 @@
|
||||
0
|
||||
0
|
||||
@ -0,0 +1,4 @@
|
||||
int a[10][10];
|
||||
int main(){
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
14
|
||||
@ -0,0 +1,9 @@
|
||||
//test array define
|
||||
int main(){
|
||||
int a[4][2] = {};
|
||||
int b[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
int c[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
|
||||
int d[4][2] = {1, 2, {3}, {5}, 7 , 8};
|
||||
int e[4][2] = {{d[2][1], c[2][1]}, {3, 4}, {5, 6}, {7, 8}};
|
||||
return e[3][1] + e[0][0] + e[0][1] + a[2][0];
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
int main(){
|
||||
const int a[4][2] = {{1, 2}, {3, 4}, {}, 7};
|
||||
const int N = 3;
|
||||
|
||||
int b[4][2] = {};
|
||||
int c[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
int d[N + 1][2] = {1, 2, {3}, {5}, a[3][0], 8};
|
||||
int d[3 + 1][2] = {1, 2, {3}, {5}, a[3][0], 8};
|
||||
int e[4][2][1] = {{d[2][1], {c[2][1]}}, {3, 4}, {5, 6}, {7, 8}};
|
||||
return e[3][1][0] + e[0][0][0] + e[0][1][0] + d[3][0];
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
//test const gloal var define
|
||||
const int a = 10, b = 5;
|
||||
|
||||
int main(){
|
||||
return b;
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
//test const local var define
|
||||
int main(){
|
||||
const int a = 10, b = 5;
|
||||
return b;
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
const int a[5]={0,1,2,3,4};
|
||||
|
||||
int main(){
|
||||
return a[4];
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
4
|
||||
@ -0,0 +1,8 @@
|
||||
int defn(){
|
||||
return 4;
|
||||
}
|
||||
|
||||
int main(){
|
||||
int a=defn();
|
||||
return a;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue