LLVMã«ã¤ãã¦ãããã¯ã¨ã³ãã®é¨åã¯ããç¨åº¦åå¼·ãããã©ãããããã°Passã®ä½ãæ¹ãã¾ããã«åå¼·ãããã¨ãç¡ãã£ãã
LLVMã¨è¨ãã°Passã ããï¼ã¨ãããã¨ã§Passã®ä½ãæ¹ã«ã¤ãã¦åå¼·ãããã¨ã«ãããããã¯ãã®ãã¡LLVMã®æ¡å¼µãæé©åããããã¨ãã«å½¹ã«ç«ã¤ã¯ãã ã
次ã«passã®ç»é²æ¹æ³ã«ã¤ãã¦ãç¸äºä¾åé¢ä¿ã«ã¤ãã¦ãªã©ã®è©±ã
LLVMã®Passãæ¸ã
Passã®ç»é²
Hello Worldã®ä¾ã§ã¯ã©ã®ããã«passã®ç»é²ãåä½ããã®ãã«ã¤ãã¦ç´¹ä»ãããããã©ã®ããã«ä½¿ç¨ããã©ã®ããã«åä½ããã®ããè¦ã¾ãããããã§ã¯ãpassãã©ã®ããã«ãã¦ãããã¦ãªãç»é²ãããã®ãã«ã¤ãã¦è°è«ãã¾ãã
ãµã³ãã«ãè¦ãããã«ãpassã¯RegisterPass
ãã³ãã¬ã¼ãã使ç¨ãã¦ç»é²ããæ¡ãããã³ãã¬ã¼ããã©ã¡ã¼ã¿ã¯passã®ååã§ãããã¯ã³ãã³ãã©ã¤ã³ã§ããã°ã©ã (ä¾ãã°ãoptãbugprintãªã©)ã«è¿½å ãããã¹ãpassã®ååãæå®ããã¨ãã«ä½¿ç¨ããã¾ããæåã®å¼æ°ã¯passã®ååã§ã-help
ã«ãã£ã¦ããã°ã©ã ããåºåãããæã«ä½¿ç¨ãããåæ§ã«-debug-pass
ãªãã·ã§ã³ã«ãã£ã¦çæãããã¡ãã»ã¼ã¸ã«ã使ç¨ããã¾ãã
passãç°¡åã«ãã³ãã§ããããã«ãããå ´åã«ã¯ã以ä¸ã®ä»®æ³printã¡ã½ãããå®è£ ããå¿ è¦ãããã¾ãã
print
ã¡ã½ãã
virtual void print(llvm::raw_ostream &O, const Module *M) const;
print
ã¡ã½ããã¯ã解æã®çµæã人éãèªããå½¢å¼ã§åºåããããã«"analyses"ã«ãã£ã¦å®è£
ãããªããã°ãªãã¾ãããããã¯è§£æã®çµæããããã°ããããã«æå¹ã§ãä»ã®äººã«ã©ã®ããã«è§£æãåä½ããã®ãã示ãã®ã«ä¾¿å©ã§ãã-analyze
å¼æ°ã«ãããã®ã¡ã½ãããèµ·åãã¾ãã
llvm::raw_ostream
ãã©ã¡ã¼ã¿ã«ããçµæãåºåããã¹ããªã¼ã ãæå®ããModule
ãã©ã¡ã¼ã¿ã¯è§£æãããããã°ã©ã ã®ãããã¬ãã«ã®ã¢ã¸ã¥ã¼ã«ã¸ã®ãã¤ã³ã¿ã示ãã¦ãã¾ããç¹å®ã®ç°å¢ä¸ã«ããã¦ãã®ãã¤ã³ã¿ãNULLã§ãã£ãå ´åã«ã¯(ä¾ãã°ããããã¬ããã®Pass::dump()
ãå¼ã³åºãããå ´å)ããã®ã¡ã½ããã¯ãããã°åºåãåä¸ãããããã ãã«ã¤åãããã¹ãã§ãããããã«ä¾åãããã¹ãã§ã¯ããã¾ããã
passéã§ã®ç¸äºä½ç¨ã®æå®
PassManager
ã®è²¬ä»»ã®å
ã®éè¦ãªãã®ã®ä¸ã¤ã«ãpassãäºãã«æ£ããç¸äºä½ç¨ãããã¨ãä¿è¨¼ãããã¨ãä¸ãããã¾ããPassManager
ã¯"passã®å®è¡ãæé©å"ãããã¨ãããããpassãã©ã®ããã«ç¸äºä½ç¨ãæ¢åã®ããã¤ãã®passã«ã©ã®ããã«ä¾åãããã«ã¤ãã¦ç¥ãå¿
è¦ãããã¾ããããã追ããããããã«ãåpassã¯ç¾å¨ã®passãå®è¡ããåã«å®è¡ããã¦ããã¹ãå¿
è¦ãªpassããç¾å¨ã®passã«ãã£ã¦ç¡æ¬§åãããã¹ãpassã®ä¸è¦§ã宣è¨ãã¦ããå¿
è¦ãããã¾ãã
å
¸åçã«ããã®æ©è½ã¯ãããªãã®passãå®è¡ãããåã«è§£æã®çµæãè¨ç®ãã¦ããå¿
è¦ãããå ´åã«ä½¿ç¨ããã¾ããä½ããã®passãç¡å¹åpassã®ä¸è¦§ãè¨å®ããå ´åã«ããã¹ã¦ã®å¤æpassãè¨ç®ãã解æã®çµæãç¡å¹åããï½ãã¨ãã§ãã¾ããããpassãgetAnalysisUsage
ã¡ã½ãããå®è£
ããªãå ´åããã®ãããªäºåã«å¿
è¦ãªpassãåå¨ããªãã¨ãããä»ã®ãã¹ã¦ã®passãç¡å¹åããã¾ãã
getAnalysisUsage
ã¡ã½ãã
virtual void getAnalysisUsage(AnalysisUsage &Info) const;
getAnalysisUsage
ã¡ã½ããã使ããã¨ã«ãã£ã¦ãããªãã®å¤æã«å¯¾ãã¦å¿
è¦ãªpassã¨ç¡å¹åãã¹ãpassã®ä¸è¦§ãæå®ãã¾ãããã®å®è£
ã§ã¯ãå¿
è¦ãªpassã¨ç¡å¹åãã¹ãpassã®ä¸è¦§ãAnalysisUsageãªãã¸ã§ã¯ãã«åããå¿
è¦ãããã¾ããããã«ãããpassã¯AnalysiUsage
ãªãã¸ã§ã¯ãã«å«ã¾ãããã®é¢æ°ãå¼ã³åºãã¾ãï¼
AnalysisUsage::addRequired<>
ã¨AnalysisUsage::addRequiredTransitive<>
ã¡ã½ãã
ããããªãã®passã(ä¾ãã°è§£æãªã©)å¥ã®passãäºåã«å®è¡ãã¦ããå¿
è¦ãããå ´åããããã®ã¡ã½ããã使ç¨ãã¦passãå®è¡ããããã«ã¢ã¬ã³ã¸ãããã¨ãã§ãã¾ããLLVMã¯DominatorSet
ããBreakCriticalEdge
ã¾ã§æ§ã
ãªç°ãªãã¿ã¤ãã®è§£æã¨passãæã£ã¦ãã¾ããä¾ãã°BreakCriticalEdge
ã¯ãããªãã®passãå®è¡ãããæã«ã¯ã¯ãªãã£ã«ã«ãªã¨ãã¸(ä¾åé¢ä¿)ãç¡ããã¨ãä¿è¨¼ãã¾ãã
ããã¤ãã®è§£æã¯ãã®ã¸ã§ããå®è¡ããããã«ä»ã®è§£æã«å¯¾ãã¦ãã§ã¤ã³ãæã£ã¦ãã¾ããä¾ãã°ãAliasAnaLysis<AliasAnaLysis>
å®è£
ã¯ä»ã®ã¨ã¤ãªã¢ã¹è§£æãã¹ã¨æ¥ç¶ãããã¨ãå¿
è¦ã§ãã解æãã§ã¤ã³ãåå¨ãã¦ããå ´åã«ã¯ãaddRequired
ã¡ã½ããã®ä»£ããã«addRequiredTransitive
ã¡ã½ããã使ç¨ããå¿
è¦ãããã¾ããããã¯ãå¿
è¦ãªãã¹ãåå¨ããéããä¸æçã«å¿
è¦ãªãã¹ãæå¹ã§ãããã¨ãPassManager
ã«ç¥ããããã®ã§ãã
AnalysisUsage::addPreserved<>
ã¡ã½ãã
PassManager
ã®ã¸ã§ãã®ä¸ã¤ã«ãã¤ã©ã®ããã«è§£æãå®è¡ãããã®ããæé©åããã¨ãããã®ãããã¾ããç¹ã«ãå¿
è¦ãªãã®ã«ãã¼ã¿ã®åè¨ç®ãçºçããã®ãé¿ããé£é³¥ãããæ¡ãããã®ãããpassã¯æ¢åã®è§£æã§å©ç¨å¯è½ãªãã®ãããã°(ä¾ãã°ãç¡å¹åãããªã)ãããäºç´ãããã¨ã宣è¨ãããã¨ã許ããã¦ãã¾ãsããã¨ããbãåç´ãªå®æ°ã®æãç³ã¿passã¯CFGãå¤æ´ããªãã®ã§ãdominator解æã®çµæã«å½±é¿ãä¸ãã¾ãããããã©ã«ãã§ã¯ããã¹ã¦ã®passã¯ãã以å¤ã®passãç¡å¹åãããã¨ãä»®å®ãã¦ãã¾ãã
AnalysisUsage
ã¯ã©ã¹ã¯addPreserved
ã«é¢é£ããç¹å®ã®ç°å¢ã«ããã¦ä¾¿å©ãªããã¤ãã®ã¡ã½ãããæä¾ãã¦ãã¾ããç¹ã«ãsetPreservesAll
ã¡ã½ããã¯LLVMã®ããã°ã©ã ã«å
¨ãå½±é¿ãä¸ããªããã¨ã宣è¨ããããã®ã¡ã½ããã§ãsetPreservesCFG
ã¯å¤æãããããã°ã©ã ä¸ã®å½ä»¤ãå¤æ´ãããCFGãããã¯çµäºå½ä»¤ã«ã¯å¤æ´ãè¡ããªããã¨ã示ãããã®ãã®ã§ãã
addPreserved
ã¡ã½ããã¯BreakCriticalEdge
ã®ããã«ç¹ã«ä¾¿å©ãªã¡ã½ããã§ãããã®passã¯å°ããªã«ã¼ãã®ã»ããã¨dominatorã«é¢é£ãã解æãã©ã®ããã«ã¢ãããã¼ãããããç¥ã£ã¦ãã¾ãããããã£ã¦å®éã«ã¯CFGã§ããã¯ããã«ãããããããããä¿åãããã¨ãã§ãã¾ãã
getAnalysisUsage
ã®å®è£
ä¾
// ãã®ä¾ã§ã¯ããã°ã©ã ãå¤æ´ããããCFGã¯å¤æ´ããªã void LICM::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<LoopInfoWrapperPass>(); }
getAnalysis<>
ã¨getAnalysisIfAvailable<>
ã¡ã½ãã
Pass::getAnalysis<>
ã¡ã½ããã¯ããªãã®ã¯ã©ã¹ããèªåçã«ç¶æ¿ãããgetAnalysisUsage
ã¡ã½ããã«ããããªããå¿
è¦ã ã¨å®£è¨ããpassã«å¯¾ããã¢ã¯ã»ã¹ãæä¾ãã¾ãããã®ã¡ã½ããã¯ã·ã³ãã«ãªãã³ãã¬ã¼ãã®å¼æ°ãåããå¿
è¦ãªpassãæå®ãããã®passã¸ã®åç
§ãè¿ãã¾ããä¾ãã°:
bool LICM::runOnFunction(Function &F) { LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); //...
ãã®ã¡ã½ããã¯ææã®passã¸ã®åç
§ãè¿ãã¾ããgetAnalysisUsage
ã®å®è£
ã§å®£è¨ããªãttããã®ã«ã¢ã¯ã»ã¹ãããã¨ããã¨ãã©ã³ã¿ã¤ã ã¢ãµã¼ã·ã§ã³ã¨ã©ã¼ãçºçãã¾ãããã®ã¡ã½ããã¯run*
ã¡ã½ããã®ãã£ããã§å¼ã³åºããã¨ãã§ããrun*
ã¡ã½ããããå¼ã³åºãããå¥ã®ãã¼ã«ã«ã¡ã½ãããããå¼ã³åºããã¨ãã§ãã¾ãã
ã¢ã¸ã¥ã¼ã«ã¬ãã«ã®passã¯é¢æ°ã¬ãã«ã®è§£ææ å ±ãã¤ã³ã¿ãã§ã¼ã¹ãéãã¦ä½¿ç¨ãããã¨ãã§ãã¾ããä¾ãã°ï¼
bool ModuleLevelPass::runOnModule(Module &M) { //... DominatorTree &DT = getAnalysis<DominatorTree>(Func); //... }
ä¸è¨ã®ä¾ã§ã¯ãDominatorTree
ã®runOnFunction
ã¯ãææã®passã®åç
§ããæ»ã£ã¦ããåã«Pass Managerã«ãã£ã¦å¼ã³åºããã¾ãã
passã«è§£æãåå¨ããå ´åã«æ´æ°ããæ©è½ãããå ´åï¼åè¿°ã®BreakCriticalEdges
ãªã©ï¼ãgetAnalysisIfAvailable
ã¡ã½ããã使ç¨ãããã¨ãã§ãã¾ãããã®ã¡ã½ããã¯ãåæãã¢ã¯ãã£ããªå ´åã«ãã®åæã¸ã®ãã¤ã³ã¿ãè¿ãã¾ããä¾ãã°ã以ä¸ã®ããã«ãªãã¾ãã
if (DominatorSet *DS = getAnalysisIfAvailable<DominatorSet>()) { // A DominatorSet is active. This code will update it. }