国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于插件的編譯原理課程實(shí)驗(yàn)設(shè)計(jì)

2011-12-31 00:00:00計(jì)衛(wèi)星王貴珍李侃
計(jì)算機(jī)教育 2011年11期


  摘要:根據(jù)編譯技術(shù)的最新進(jìn)展及目前廣泛使用的各種編譯器框架,提出基于插件的編譯原理課程實(shí)驗(yàn)設(shè)計(jì)的思想與方法,解除后端實(shí)踐依賴于前端分析結(jié)果的限制,使學(xué)生能夠利用現(xiàn)有的編譯器框架直接進(jìn)行后端語(yǔ)義分析、代碼優(yōu)化和代碼生成等方面的實(shí)踐;同時(shí),文章介紹了基于插件的編譯原理課程實(shí)驗(yàn)設(shè)計(jì)的必要性、可能性,并以Phoenix編譯器框架為例說(shuō)明了該方案的可行性。
  關(guān)鍵詞:編譯原理;課程實(shí)驗(yàn);插件;Phoenix
  
  編譯程序各個(gè)邏輯功能之間具有較強(qiáng)的依賴性,如后端的語(yǔ)義分析和中間代碼生成、代碼優(yōu)化、目標(biāo)代碼生成等都依賴于前端的正確分析與處理。如果沒(méi)有前端的輸出,就無(wú)法進(jìn)行后續(xù)的加工和處理。考慮到編譯原理程序本身組織結(jié)構(gòu)的特點(diǎn)、教學(xué)學(xué)時(shí)限制和學(xué)生實(shí)踐動(dòng)手能力等因素,目前課程實(shí)踐環(huán)節(jié)普遍向編譯器前端靠攏[1-2]。即使設(shè)置了與后端相關(guān)的實(shí)驗(yàn),學(xué)生也往往無(wú)法完成。因此目前比較缺乏針對(duì)后端處理的、較為獨(dú)立的小規(guī)模課程實(shí)驗(yàn)供學(xué)生練習(xí),這勢(shì)必影響學(xué)生對(duì)編譯器整體性的掌握及對(duì)編譯器各部分有機(jī)關(guān)聯(lián)和接口的學(xué)習(xí)理解。
  隨著計(jì)算機(jī)體系結(jié)構(gòu)的不斷發(fā)展,編譯技術(shù)也在不斷進(jìn)步和變化。為了快速對(duì)各種研究思想進(jìn)行驗(yàn)證,并縮短編譯相關(guān)研究成果與實(shí)際實(shí)現(xiàn)之間的轉(zhuǎn)換時(shí)間,各種供研究人員使用的編譯器框架平臺(tái)應(yīng)運(yùn)而生。例如,微軟公司推出的Phoenix編譯器框架[3]、開(kāi)源的Open64和GCC等。這些已有的編譯器框架能夠簡(jiǎn)化編譯程序的設(shè)計(jì)與實(shí)現(xiàn);同時(shí),為了支持編譯器的定制及相關(guān)理論的快速驗(yàn)證,有些編譯器框架(如Phoenix和GCC4.5)允許以插件的形式對(duì)部分處理階段進(jìn)行修改或者加強(qiáng)?;诓寮脑O(shè)計(jì)方法對(duì)于研究人員而言其價(jià)值是毋容置疑的,同時(shí)也為編譯原理課程實(shí)踐提供了便利。我們可以利用這些編譯框架提供的前端分析與識(shí)別功能,以及后端的部分處理能
  力,設(shè)計(jì)針對(duì)語(yǔ)義分析與中間代碼生成、代碼優(yōu)化和目標(biāo)代碼生成相關(guān)的實(shí)驗(yàn)環(huán)節(jié),其好處在于:
  1) 可以縮短實(shí)驗(yàn)完成所需要的時(shí)間,降低實(shí)驗(yàn)的難度,從而為教學(xué)目標(biāo)的完成奠定良好基礎(chǔ);
  2) 能夠培養(yǎng)學(xué)生的科研能力和創(chuàng)新意識(shí),為使他們順利走上科研道路打下堅(jiān)實(shí)的基礎(chǔ);
  3)基于插件的設(shè)計(jì)思想和技術(shù)也是目前許多大型軟件的普遍設(shè)計(jì)與實(shí)現(xiàn)方法,如Firefox、Eclipse和IDA Pro等。學(xué)生通過(guò)基于插件的課程實(shí)驗(yàn)?zāi)軌蚣訌?qiáng)學(xué)生對(duì)大型復(fù)雜軟件架構(gòu)、設(shè)計(jì)思想和實(shí)現(xiàn)方法等各個(gè)方面的認(rèn)識(shí),提升軟件工程管理和軟件設(shè)計(jì)水平。
  目前清華大學(xué)“編譯原理專題訓(xùn)練”課程已經(jīng)將開(kāi)放源碼軟件GCC和Open64作為實(shí)驗(yàn)框架引入實(shí)踐教學(xué)[4],GCC 4.5及以上版本已經(jīng)實(shí)現(xiàn)了對(duì)插件設(shè)計(jì)的支持。筆者僅以微軟的Phoenix為例詳細(xì)說(shuō)明基于插件的實(shí)驗(yàn)設(shè)計(jì)的可行性。
  1Phoenix編譯框架
  Phoenix是由微軟公司新推出的用于構(gòu)造編譯程序,各種程序分析、優(yōu)化和測(cè)試工具的一個(gè)基礎(chǔ)框架。Phoenix編譯器框架主要功能包括:
  1)Phoenix是一個(gè)編譯器。該編譯器有著與其他編譯器相似的功能,能夠?qū)⒃创a編譯為二進(jìn)制代碼。
  2) 是一個(gè)編譯器開(kāi)發(fā)工具。由于Phoenix采用了統(tǒng)一的中間形式,編譯器開(kāi)發(fā)者只需將新語(yǔ)言的源程序轉(zhuǎn)化為這種中間形式,然后就可利用Phoenix后端工具完成中間語(yǔ)言的轉(zhuǎn)化、優(yōu)化以及二進(jìn)制代碼的生成。
  3)Phoenix作為一個(gè)框架,同時(shí)還是可插接的(Plug-in),Phoenix包含一些API,使用這些API能編寫利用Phoenix特性的工具。
  Phoenix體系結(jié)構(gòu)具有高度的可伸縮性,使得開(kāi)發(fā)者或研究人員能夠在該體系結(jié)構(gòu)上開(kāi)發(fā)各種各樣的編譯器以及分析優(yōu)化工具。在Phoenix中,遍(Pass)和階段(Phase)是兩個(gè)極重要的概念,也是支持插件式設(shè)計(jì)的主要結(jié)構(gòu)。Phoenix支持多遍處理,因此后端由多個(gè)Pass構(gòu)成,而且允許使用者插入自己的Pass,用于特定處理。一個(gè)函數(shù)的分析過(guò)程可以劃分為若干階段,每個(gè)階段的處理對(duì)應(yīng)一個(gè)Phase。使用者可以插入、刪除一個(gè)Phase或重新排列原有的Phase,Pass和Phase的關(guān)系如圖1所示。
  2基于插件的課程實(shí)驗(yàn)設(shè)計(jì)
  插件是指能夠被Phoenix核心編譯模塊(C2.exe)調(diào)用的外部模塊。假設(shè)設(shè)計(jì)了一個(gè)名為MyPlugin.dll的插件,當(dāng)使用命令行選項(xiàng)-d2plugin:MyPlugin.dll啟動(dòng)C2時(shí),C2就會(huì)在編譯的過(guò)程裝載并執(zhí)行MyPlugin.dll中的代碼。
  如圖2所示,源代碼程序經(jīng)過(guò)前端C1.exe的分析和處理之后,然后交給C2中的各個(gè)Pass和Phase進(jìn)行處理。當(dāng)C2運(yùn)行時(shí),Myplugin能夠訪問(wèn)C2內(nèi)部的所有數(shù)據(jù)結(jié)構(gòu),因此,通過(guò)MyPlugin能夠改變C2的行為,如增加新的Phase,旁路已經(jīng)存在的Phase,或者替換可選的Phase等。例如,Myplugin可以提供一個(gè)寄存器分配Phase替換掉C2中已有的部分,可以向被編譯的每個(gè)函數(shù)中插入一些其他的代碼,輸出某個(gè)函數(shù)編譯所形成的IR等。
  編寫一個(gè)Phoenix的插件非常簡(jiǎn)單,例如,我們想輸出被編譯的每個(gè)函數(shù)的名字,則需要編寫一個(gè)插件FuncNames。為此,首先定義一個(gè)實(shí)現(xiàn)PlugIn接口的類MyPlugIn,作為插件FuncNames與C2.exe交互的接口。MyPlugIn必須實(shí)現(xiàn)PlugIn中的兩個(gè)接口:RegisterObjects和BuildPhase。Phoenix編譯框架在裝載插件之后調(diào)用RegisterObjects并注冊(cè)插件對(duì)命令行選項(xiàng)進(jìn)行處理。本例中不支持任何命令行命令,所以該接口的實(shí)現(xiàn)為空。BuildPhase接口有一個(gè)PhaseConfiguration類型的參數(shù),這個(gè)參數(shù)是C2.exe提供給插件的,插件中的代碼通過(guò)這個(gè)參數(shù)能夠訪問(wèn)C2中的Phase列表。本例中我們只需要?jiǎng)?chuàng)建一個(gè)新的Phase實(shí)例并將其插入到列表中合適的位置就可以了,程序代碼如下:
  
  class MyPlugIn : Phx::PlugIn{
  ...
   virtual void RegisterObjects() override;
   virtual void BuildPhases ( Phx::Phases:: PhaseConfiguration ^ config ) override;
  ...
  };
  void MyPlugIn::RegisterObjects() {}
  void MyPlugIn::BuildPhases( Phx::Phases::PhaseConfiguration ^ config) {
   Phx::Phases::Phase ^ encodingPhase;
   Phx::Phases::Phase ^ funcNamesPhase;
   encodingPhase = config->PhaseList->FindByName ("Encoding");
   funcNamesPhase = MyPhase::New(config);
   encodingPhase->InsertBefore(funcNamesPhase);
  }
  
  此外我們需要?jiǎng)?chuàng)建的一個(gè)新的Phase類,該類是從父類Phase繼承而來(lái),且其必須實(shí)現(xiàn)父類的兩個(gè)方法New和Execute。New是在前述的BuildPhases方法中調(diào)用的,主要作用是構(gòu)造和初始化MyPhase對(duì)象;而Execute是C2編譯每個(gè)方法時(shí)都會(huì)調(diào)用的方法,實(shí)際完成函數(shù)名輸出的方法,程序代碼如下:
  
  
  class MyPhase : Phx::Phases::Phase{
  ...
   static Phx::Phases::Phase ^New ( Phx:: Phases::PhaseConfiguration ^ config );
   virtual voidExecute (Phx::Unit ^ unit ) override;
  };
  Phx::Phases::Phase ^ MyPhase::New( Phx:: Phases::PhaseConfiguration ^ config) {
   Phase ^ phase = gcnew MyPhase();
   phase->Initialize(con

虹口区| 马鞍山市| 西平县| 石首市| 苏尼特左旗| 金湖县| 孟连| 衡山县| 襄垣县| 德清县| 丹棱县| 工布江达县| 瑞昌市| 蒙阴县| 松滋市| 高州市| 峨眉山市| 涿鹿县| 鸡泽县| 蒲城县| 兴文县| 崇仁县| 通河县| 萨嘎县| 利川市| 芦溪县| 旌德县| 肃宁县| 琼结县| 禹城市| 阿拉善右旗| 道真| 海口市| 临泽县| 柘荣县| 新兴县| 安平县| 翁牛特旗| 贵德县| 和田县| 汶川县|