Tag: 代码生成

使用Sethi-Ullman算法的表达式代码生成器

给一个AST树 ,我想生成一个类似汇编的语言。 我正在尝试使用Sethi-Ullman算法,但我在算法实现中有一些问题。 我用完寄存器后该怎么办? 目前我做以下事情: 发出一个push REG ,其中REG是右子树的寄存器,评估左子树,得到一个自由寄存器指定为右子树的寄存器,然后发出POP REG操作,其中REG也是右子树的寄存器。 我该如何实现该function以获得免费注册? 目前我正在使用这样的实现而不是基于堆栈: enum Reg { Reg_r0, Reg_r1 }; Reg regs[] = { Reg_r0, Reg_r1 }; Reg getreg() { static int c; if(c == sizeof(regs) / sizeof(int)) c = 0; return regs[c++]; } 这是一个伪代码(来自C语言)如何从我unsertood(包括label()函数)实现它 // K is the number of registers available int K = 2; void […]

避免gccfunction序幕开销?

我最近遇到了很多函数,其中gcc在x86上生成了非常糟糕的代码。 它们都符合以下模式: if (some_condition) { /* do something really simple and return */ } else { /* something complex that needs lots of registers */ } 将简单的情况看作是一个非常小的东西,以至于一半或更多的工作花在推动和弹出不会被修改的寄存器上。 如果我手动编写asm,我会在复杂的情况下保存并恢复已保存的跨调用寄存器,并且在简单的情况下完全避免触及堆栈指针。 有没有什么方法可以让gcc变得更聪明并且自己做到这一点? 最好使用命令行选项,而不是源代码中的丑陋黑客… 编辑:为了使它具体化,这里有一些非常接近我正在处理的一些函数: if (buf->pos end) { return *buf->pos++; } else { /* fill buffer */ } 另一个: if (!initialized) { /* complex initialization procedure */ } […]

为什么在大括号初始化中允许参数列表中不允许使用额外的逗号?

跟进我的一个老问题( 在大括号初始化结束时是否与额外的“,”相关? ) 是否有任何技术原因导致函数声明和函数调用中的参数列表没有像大括号初始化一样对代码生成友好? 我的意思是: 这没关系,额外的,被忽略了: int generated_array[] = { 1, 2, 3, }; 为了保持一致性,允许这样做也没有意义吗? int someFunc( int v1, int v2, int v3, ){…} int ret_val = someFunc( 1, 2, 3, ); 我看不出它会如何使编译变得更复杂,但也许有些东西我没想到。 我猜它实际上会略微简化它。 当然,人们可以争辩说它不像大括号初始化那么有用,但是如果允许的话,应该有代码生成至少要简单一点的情况。

在C中模拟lambdas?

我应该提一下,我在C中生成代码,而不是手动执行此操作。 我这样说是因为如果背后有很多代码并不重要,因为编译器应该管理它。 无论如何,我如何在C中模拟lambda? 我以为我可以在源代码中的某处生成一个带有随机名称的函数然后调用它? 我不太确定。 我还没有真正尝试过任何东西,因为我想在实现它之前把想法弄清楚。 是否有某种预处理器指令可以做,或者某些宏可以使这个更清洁? 我受到了Jon Blow的启发,尝试编译器开发,他似乎用他的语言Jai实现了Lambdas。 但是,我认为他做了一些他生成字节码然后进入C的东西? 我不确定。 编辑:我正在编写一个编译器,编译器只是我的一个项目让我忙碌,而且我想了解更多有关编译器的知识。 我主要使用clang,我使用的是Ubuntu 14.10。 我没有任何垃圾收集,但我想尝试使用某种智能指针-y / rust / ARC启发的内存模型来进行垃圾收集,即几乎没有开销。 我选择C是因为我想更多地涉足它。 我的项目是免费软件,只是一个爱好项目。

possible(x)和__builtin_expect((x),1)

我知道内核使用了likely , unlikely宏。 宏的文档位于内置函数:long __builtin_expect(long exp,long c) 。 但他们并没有真正讨论细节。 编译器究竟如何处理likely(x)和__builtin_expect((x),1) ? 它是由代码生成器还是优化器处理的? 它取决于优化级别吗? 代码生成的示例是什么?

gcc的primefaces操作和代码生成

我正在考虑通过gcc查看为primefaces操作生成的一些程序集。 我尝试了以下短序列: int x1; int x2; int foo; void test() { __atomic_store_n( &x1, 1, __ATOMIC_SEQ_CST ); if( __atomic_load_n( &x2 ,__ATOMIC_SEQ_CST )) return; foo = 4; } 看看Herb Sutter关于代码生成的primefaces武器谈话,他提到X86手册要求将xchg用于primefaces存储,并使用简单的mov来进行primefaces读取。 所以我期待的是: test(): .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $1, %eax xchg %eax, x1(%rip) movl x2(%rip), %eax testl %eax, […]