diff --git a/.gitignore b/.gitignore
index 278f4e458d09b5b2b03fb6922f0926769a5577b4..667035bcb0d88776afacbf6cd9ae9612f2f210c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,6 @@ target
 *.log
 test/lib/sylib.ll
 .VSCodeCounter
-*.pri.*
\ No newline at end of file
+*.pri.*
+test/performance
+performance_log
\ No newline at end of file
diff --git a/script/common.sh b/script/common.sh
index 71aab37b7673fc77411c04a2ad0f30d80f40729b..50183862be132079b5a2c55c5b6f27214d76492b 100644
--- a/script/common.sh
+++ b/script/common.sh
@@ -25,7 +25,7 @@ function runone_ir {
     file=$2
     name=$(basename $file)
     printf "${RED}--- Compile IR ${file} ---${NC}\n"
-    compile_one $file $BASEDIR/target/test/${category}/${name}.ll
+    compile_one $file $BASEDIR/target/test/${category}/${name}.ll > /dev/null
     clang $BASEDIR/test/lib/sylib.ll $BASEDIR/target/test/${category}/${name}.ll -o $BASEDIR/target/test/${category}/${name}.elf
     printf "${RED}--- Testing IR ${file} ---${NC}\n"
     if [ ! -f $BASEDIR/test/${category}/${name%.*}.in ]; then
@@ -42,7 +42,7 @@ function runone_asm {
     file=$2
     name=$(basename $file)
     printf "${RED}--- Compile ASM ${file} ---${NC}\n"
-    compile_one $file $BASEDIR/target/test/${category}/${name}.S
+    compile_one $file $BASEDIR/target/test/${category}/${name}.S > /dev/null
     arm-linux-gnueabihf-gcc -march=armv7-a -mfpu=vfpv3 -static $BASEDIR/target/test/${category}/${name}.S $BASEDIR/test/lib/libsysy.a -o $BASEDIR/target/test/${category}/${name}.arm.elf
     printf "${RED}--- Testing ASM ${file} ---${NC}\n"
     if [ ! -f $BASEDIR/test/${category}/${name%.*}.in ]; then
diff --git a/script/functional_checker.py b/script/functional_checker.py
index ba49e34e4c094a2f20def386c16226f696764266..596147510c1faf8cca390d58e33771192d8d8f70 100755
--- a/script/functional_checker.py
+++ b/script/functional_checker.py
@@ -34,7 +34,7 @@ def test(target_elf, out_file, in_file=None, is_asm=False):
     NC='\033[0m' # No Color
 
     if out.strip() == s.strip():
-        print(err) # perfomance test打印所花时间
+        print(err, file=sys.stderr) # perfomance test打印所花时间
         print(RED+"=========== Pass! ==============" +NC)
         return True
     else:
@@ -44,10 +44,10 @@ import os
 
 proj_dir = os.path.dirname(os.path.dirname(__file__))
 debug_case = None
-# debug_case = '54_hidden_var' # uncomment to debug
+# debug_case = '00_bitset1' # uncomment to debug
 if debug_case:
     assert len(sys.argv) == 1
-    sys.argv = ['debugasm', f'{proj_dir}/script/functional_checker.py', f'{proj_dir}/target/test/functional/{debug_case}.sy.elf', f'{proj_dir}/test/functional/{debug_case}.out']
+    sys.argv = [f'{proj_dir}/script/functional_checker.py', 'debugasm', f'{proj_dir}/target/test/performance/{debug_case}.sy.arm.elf', f'{proj_dir}/test/performance/{debug_case}.out']
 print(sys.argv)
 
 if len(sys.argv) < 4:
@@ -68,9 +68,11 @@ if len(sys.argv) >= 5:
     in_file = sys.argv[4]
 if mode == 'ir':
     ret = test(target_elf, out_file, in_file, is_asm=False)
-    exit(ret!=True)
+    if (not ret):
+        exit(-1)
 elif mode == 'asm':
     ret = test(target_elf, out_file, in_file, is_asm=True)
-    exit(ret!=True)
+    if (not ret):
+        exit(-1)
 else:
     assert False
\ No newline at end of file
diff --git a/script/functional_test.sh b/script/functional_test.sh
index b9ddd32e8a58b4a96b7fcb839f0fecfe3d82f113..54f0b11347b155cd2f076b970749663a4b808d2d 100755
--- a/script/functional_test.sh
+++ b/script/functional_test.sh
@@ -22,12 +22,12 @@ for file in $BASEDIR/test/functional/*.sy; do
     IFS='_' array=($name_)
     IFS=$beforeIfs
 
-    if [ ${array[0]} -lt $1 ] ; then
+    if [ ${array[0]} -lt ${1:-0} ] ; then
         echo "skip ${array[0]}"
         continue
     fi
     
-    runone_ir functional $file
+    # runone_ir functional $file
 
     runone_asm functional $file
 done
\ No newline at end of file
diff --git a/script/performance_test.sh b/script/performance_test.sh
index 69dc69bdbbdbf15db25b5977df284c0e6723b4ee..c1d19156ba0ed87c96d2d6e1fec44dac352a0218 100644
--- a/script/performance_test.sh
+++ b/script/performance_test.sh
@@ -17,17 +17,10 @@ fi
 set -e; # error exit
 
 for file in $BASEDIR/test/performance/*.sy; do
-    name_=$(basename $file)
-    beforeIfs=$IFS
-    IFS='_' array=($name_)
-    IFS=$beforeIfs
+    # 性能测试后面很多文件名没有带01_这样的标号,因此不支持从第n个开始
 
-    if [ ${array[0]} -lt $1 ] ; then
-        echo "skip ${array[0]}"
-        continue
-    fi
-    
-    runone_ir performance $file
+    # runone_ir performance $file
 
-    runone_asm performance $file
+    # 把运行时间放到一个单独的文件,方便对比
+    runone_asm performance $file 2>> ./performance_log
 done
\ No newline at end of file
diff --git a/src/main/java/backend/arm/LocalRegAllocator.java b/src/main/java/backend/arm/LocalRegAllocator.java
index 82ab2c6d1f5e242f8134897cb45586f57330e516..2badb297419c4c84fe205b8a8fc56a7b7dfb8c57 100644
--- a/src/main/java/backend/arm/LocalRegAllocator.java
+++ b/src/main/java/backend/arm/LocalRegAllocator.java
@@ -134,7 +134,10 @@ public class LocalRegAllocator {
         private void spillInd(int ind, boolean isFloat, AsmBlock blk, List<AsmInst> toInsertBefore) {
             RegClass rc = rcs[b2i(isFloat)];
             var toSpillVreg = rc.current[ind];
-            StackOperand spilledLoc = allocateOrGetSpill(toSpillVreg);
+            StackOperand spilledLoc = allocateOrNullSpill(toSpillVreg);
+            if(spilledLoc == null) {
+                return;
+            }
             AsmInst store;
             var to = ind2Reg(ind, isFloat);
             if (isFloat) {
@@ -146,6 +149,31 @@ public class LocalRegAllocator {
             toInsertBefore.addAll(Generator.expandStackOperandLoadStoreIP(store));
         }
 
+        // allocateOrGetSpill的修改版,如果local值获取过spill区域,则说明这个值被保存过。
+        // 而每个vreg只有一个live range,则说明不需要再额外生成store了
+        private StackOperand allocateOrNullSpill(VirtReg vreg) {
+            StackOperand spilledLoc;
+            if (globs.contains(vreg)) {
+                spilledLoc = globSpill.get(vreg);
+                if (spilledLoc == null) {
+                    spilledLoc = new StackOperand(StackOperand.Type.SPILL, func.sm.allocSpill(4));
+                    spilledLoc.comment = vreg.comment;
+                    globSpill.put(vreg, spilledLoc);
+                }
+            } else {
+                spilledLoc = localSpill.get(vreg);
+                if (spilledLoc != null) {
+                    return null;
+                }
+                if (spilledLoc == null) {
+                    spilledLoc = new StackOperand(StackOperand.Type.SPILL, func.sm.allocSpill(4));
+                    spilledLoc.comment = vreg.comment;
+                    localSpill.put(vreg, spilledLoc);
+                }
+            }
+            return spilledLoc;
+        }
+
         private StackOperand allocateOrGetSpill(VirtReg vreg) {
             StackOperand spilledLoc;
             if (globs.contains(vreg)) {