可以以并行模式运行其组件的编译器

时间:2014-05-21 14:54:29

标签: compiler-construction

我们今天有一个编译器基础架构,它可以以并行模式运行其组件以提高编译速度吗?例如,当代码生成器开始发出目标平台的代码时,可能,编译器基础结构可以执行词法&同时对下一个源文件进行语法分析。我们在这个主题上有相关的研究吗?

UPD0:This是一个相对的答案。

2 个答案:

答案 0 :(得分:2)

LLVM不执行多线程编译,但理论上它可能因为每个编译器传递只能改变某个范围'他们的。来自the docs

  

根据传递的工作方式,您应该继承ModulePass,CallGraphSCCPass,FunctionPass或LoopPass,或RegionPass或BasicBlockPass类,这样可以为系统提供有关传递内容的更多信息,以及如何将其与其他通行证。 LLVM Pass Framework的一个主要特性是它根据你的pass所遇到的约束(它们从哪个类派生出来)来安排传递以高效的方式运行。

实际上,编译器传递中的细粒度并行性可能不值得同步的开销(并且当传递接触的次数超过其声称时不可避免的错误),因为可以编译大型程序中的各个源文件在平行下。不同的传递类主要用于文档。它们还可以以缓存友好的方式帮助调度传递;例如,当在所有翻译单元的函数上运行一堆FunctionPasses时,在移动到下一个函数之前,在一个函数上运行每个传递(保持在缓存中)会更快。

答案 1 :(得分:0)

我们的DMS软件再造工具包就是这样做的。

DMS是用于构建任意,自定义程序分析和转换工具的基础架构。它具有内置机制,支持完全无上下文的解析,符号表/控制流/数据流图构建,以及源级模式匹配和源到源转换。给定编程语言描述(BNF的组合,属性语法,支持符号表的语言特定事实集合,控制/数据流事实等),DMS将源文本解析为AST,并运行各种事实收集器(通常实现)作为属性语法)来构建经典的编译器数据结构。它适用于C,C ++ 14,Java 1.8和各种其他语言。

由于DMS的主要用例是用于整个程序分析和转换,因此性能很重要。因此,DMS是在并行编程PARLANSE中实现的,这使得细粒度不规则大小的任务并行性可用且高效(~50个机器指令开销,相当于fork和join,总计)[可以并行化的大块程序是很难找到]。一个在DMS应用程序中使用这种并行性取决于工具工程师,但它在很多地方都很容易使用。基线,DMS支持的所有数据结构都是并行安全的;许多内部算法在实际应用中并行实现。与语言前端相关联的属性语法很大程度上是功能性的;它们被编译为PARLANSE偏序并行结构。暴露的不规则并行性由工作窃取调度程序执行;程序员永远不会分配或安排线程。 [所有这些都在Windows的库存上运行]。

DMS使用并行性的一些地方:

  • 流媒体词法分析器。词法分析器可以(并且在某些应用程序中)通过生成流与解析分离。词法分析器可以独立于解析器(或其他词法分析工具)正在执行的操作生成词位。蒸汽以相对明显的方式作为生产者/消费者队列进行管理。
  • 符号表构造:标识符用于类型的映射。这通常在传递时向下构成树爬行根以形成作为期货的范围,并在第二次传递时向上移动以收集标识符,确定它们被识别的范围和/或在范围中插入标识符声明。这很平行并行。在整个程序级别,人们经常发现一个模块中使用的符号在其他模块中完全定义(Java是特别好的例子);现在需要按需启动解析和名称解析来提供这样的引用数据。对于我们的Java前端,这是通过快速内部分支实现的;分叉计算设置了未来"为了获得理想的结果并等待,释放处理器去做其他工作。给定数千个要处理的Java文件的完整Java前端同时运行并行分析,用于符号表构造的属性语法和用于跨编译单元的依赖性的动态部分顺序构造。这使得8或16核CPU非常繁忙。 (我们有完整的C和C ++解析器;我们尚未将这些想法应用于预处理,但它在我们的待办事项列表中。)
  • 代码转换的并行应用。给定一组转换或简化,它们可以轻松并行地应用于单独的编译单元,并在编译单元中分离子树。 (有些人可能会说你可以在完全独立的过程中应用转换,这是真的,但那些单独的过程将各自单独地执行上面描述的名称和类型解析。)
  • 排序。在DMS中有大量列表需要排序的各种地方。我们将它们作为递归的并行合并排序运行。
  • 具体应用。我们的基于DMS的CloneDR可以在大型源代码库中找到重复的代码,并行执行克隆检测。

我们没有做的是经典编译(目标代码的源代码)。没有任何理由我们无法并行执行此操作,但DMS的主要应用程序无法编译。我们看到很多编译器,并没有看到复制他们所做的很多重点。