【问题标题】:Register allocation for code generator in MIPSMIPS 中代码生成器的寄存器分配
【发布时间】:2021-05-19 16:49:37
【问题描述】:
program main();
     a,b: integer;
     function p(name x: integer; var y,z: integer): integer;
         a: integer;
         function f(y: integer): integer;
             b,c: integer;
             a := a+1;
             if (g(y<=0)) then return 2;
             return 2*x + p(y--/2,b,c) – b*c;
         end function;
         function g(name i: integer): integer;
             if (b < 3) then return 1;
             return i;
         end function;
         a := b++;
         y := f(x);
         z := y*f(x) – a;
         return a;
     end function;
     a := 1;
     b := 6;
     p(a+b--,a,b);
     print(a,b);
 end program

这是程序,我想在其中为 MIPS 中的代码生成器分配寄存器。我对嵌套函数有问题。 我的收银机是:2-25 美元。 寄存器 $4-$7 用于传递参数,$3 用于调用函数时的通道访问链接,$2 用于函数结果。寄存器 $16-$23 在调用函数时必须保持其值,因此如果它们被绑定,则必须通过进入函数并将它们存储在堆栈中的辅助位置并 在退出函数之前重新加载。如果字长为 4 字节,每个代码单元的激活记录大小是多少,包括参考评估子程序的参数? 还有,需要分配多少个寄存器,需要分配哪些?

【问题讨论】:

    标签: function nested mips allocation subroutine


    【解决方案1】:

    由于这种编程语言是假设性的,我们必须对修改var 参数的可见性的即时性做出一些假设。让我们假设这些更改(对var 参数)是立即可见的,因此它们是通过地址有效传递的。

    因此,出于所有实际目的,在var 位置中传递的实际参数必须是内存变量,并且传递它们的地址而不是它们的当前值(否则就是这种情况)。


    (当然,还有其他方法可以做到这一点:高级优化可能会内联其中一些函数(p 是递归的,因此很难完全内联,尽管尾递归可能是与进一步修改一起应用以使其迭代而不是递归),否则,为每个特定调用站点自定义生成代码是另一种可能性。)


    因此,在这些假设下,main.amain.b 都被“强制”到(堆栈)内存,因为p(a+b--,a,b); 此外,因为p(y--/2,b,c)p.bp.c 也都是“强迫”记忆。

    除了这些变量被分配堆栈内存位置,您可以正常进行寄存器分配。


    由于假设的编程语言的无证性质,也使事情复杂化的是表达式的求值顺序。这个代码示例充满了歧义,使用了变量和对它们的修改(例如,b-- 与使用 b 的表达式相同),这在 C 中会导致龙的领域:未定义的行为。

    一个合理的假设是评估顺序是从左到右的,并且会立即观察到副作用(例如递减后)。

    但我们不懂语言。因此,可以说这段代码充满了特定语言的地雷,而我们不了解该语言。

    【讨论】:

    • 感谢您的评论。这种语言就像 C。
    • 寄存器是怎么分配的?
    • 不,它不像 C:C 既没有嵌套函数也没有 var 参数,所以 C 没有定义这些概念。 C 确实指定操作的顺序是未定义的,并且依赖它们会使您陷入未定义的行为,这是一个不好的地方。
    • 如果语言类似于 C,那么 return 2*x + p(y--/2,b,c) – b*c;p(a+b--,a,b); 都会与未定义的行为发生冲突,而您的教师将疏忽将其呈现为合法的 C 表达式。后者使用后递减和在同一表达式中递减的值(例如b-- + b 是 ub,非常糟糕)。前者使用这些b & c 作为var 参数,也直接在表达式中(*),在类 C 语言中也是不好的 ub。
    • b-- + b 这样的表达式合法的唯一方法是定义表达式中的评估顺序以及表达式中b-- 的副作用和可见性(C 明确避免以便让编译器灵活地为任何给定平台做最有效的事情,用于没有 ub 的表达式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多