3.11.2. 模式分析
globalisel
是以dag
指令選擇的
td定義處理與分析為基礎的。因此,
globaliselemitter
包含了乙個
codegendagpatterns
型別的const
成員cgp
(一旦建立完成,就是唯讀的),在
globaliselemitter
建構函式中將完成
dag指令選擇令人眼花繚亂的準備工作(參考
dag指令選擇器的生成**
一節,直到
match物件序列的優化
為止),為
globaliselemitter
準備好指令的
patterntomatch
例項。在此基礎上,
globalisel
將生成自己的指令匹配表。
在完成globaliselemitter
物件的構造後,立即呼叫下面的方法進行
globalisel
**生成的處理。
4240
void globaliselemitter::run(raw_ostream &os) else
4252
}4253
}4254
4255
// track the run-time opcode values
4256
gatheropcodevalues();
4257
// track the run-time llt id values
4258
gathertypeidvalues();
4259
4260
// track the ginodeequiv definitions.
4261
gathernodeequivs();
4262
4263
emitsourcefileheader(("global instruction selector for the " +
4264
target.getname() + " target").str(), os);
4265
std::vectorrules;
4266
// look through the selectiondag patterns we found, possibly emitting some.
4267
for (const patterntomatch &pat : cgp.ptms()) else
4281
++numpatternimportsskipped;
4282
continue;
4283
}4284
4285
if (rulecoverage)
4292
rules.push_back(std::move(matcherorerr.get()));
4293
}3.11.2.1. 準備工作
這實際上就是所謂的
selectiondag
定義的匯入。 在
globaliselemitter::run()
的4256
行globaliselemitter::gatheropcodevalues()
收集指令操作碼的值。
3081
void globaliselemitter::gatheropcodevalues()
instructionopcodematcher
的opcodevalues
是densemap
型別的靜態容器。在
1554
行getinstructionsbyenumvalue()
以這個次序返回
codegeninstruction
物件:
在targetopcodes.def
檔案中宣告的固定
/通用指令
按名字字母序排序的偽指令
按名字字母序排序的其他指令
1550
static void initopcodevaluesmap(const codegentarget &target)
接著,呼叫
globaliselemitter::gathertypeidvalues()
3085
void globaliselemitter::gathertypeidvalues()
lltoperandmatcher
的靜態容器
typeidvalues
的型別是
std::map
,而全域性容器
knowntypes
的型別是
std::set
。knowntypes
是由lltoperandmatcher
建構函式填充的,目前尚未呼叫
lltoperandmatcher
建構函式,因此下面
1134
行迴圈在這裡不會執行。
inittypeidvaluesmap()
另外的呼叫機會在
lltoperandmatcher::hasvalue()裡:
1156
bool hasvalue() const override
這裡才是保證
typeidvalues
反映已知型別的所在。 類
lltcodegen
名字中的
llt是
low level type
的縮寫,這個類只有乙個
llt型別的資料成員,它用於輔助輸出
globalisel
生成**中與
llt相關的**。
1130
static void inittypeidvaluesmap()
接著,在
globaliselemitter::run()
的4261
行呼叫globaliselemitter::gathernodeequivs()
將sdnode
節點與等價的
globalisel
節點關聯起來:
3103
void globaliselemitter::gathernodeequivs()
3115
3116
assert(sdnodexformequivs.empty());
3117
for (record *equiv : rk.getallderiveddefinitions("gisdnodexformequiv"))
3120
}globaliselemitter
的容器nodeequivs
用於對映
sdnode
到ginodeequiv
,維護sdnode
與指令間的等價性。它的型別是
densemap。
容器complexpatternequivs
用於維護
complexpattern
與gicomplexoperandmatcher
間的等價性。它的型別也是
densemap。
同理,容器
sdnodexformequivs
用於維護
sdnodexform
與gicustomoperandrenderer
間的等價性,型別仍然是
densemap。
它們都使用相應的
selectiondag
定義的record
物件作為鍵值。
我的LLVM學習筆記 編寫LLVM demo
一 安裝llvm 二 使用clion建立demo工程 main.cpp 如下 include llvm ir verifier.h include llvm executionengine genericvalue.h include llvm executionengine interpreter...
Python 學習筆記 5 3 匿名函式
當我們在傳入函式時,有些時候,不需要顯式地定義函式,直接傳入匿名函式更方便。在python中,對匿名函式提供了有限支援。還是以map 函式為例,計算f x x2時,除了定義乙個f x 的函式外,還可以直接傳入匿名函式 list map lambda x x x,1,2,3,4,5,6,7,8,9 1...
LLVM 編譯器學習筆記之六 預處理
1 llvm 中使用builder.definemacro定義builtin巨集,類似gcc的builtin define,以下是llvm8 中定義對gcc 4.2.1版本相容性巨集 gnuc 的示例 配套的介面還有ismacrodefined及undefinemacro 2 巢狀優先順序 在 bu...