ytgui / temp

0 stars 0 forks source link

LLVM 2 - Tricks #26

Closed ytgui closed 5 years ago

ytgui commented 5 years ago

迷之缩写

TLIP TargetLibraryInfoWrapperPass TLI TargetLibraryInfo MRI MachineRegisterInfo TRI TargetRegisterInfo

Pass 执行逻辑

# Pass 执行过程 bool PassManagerImpl::run(Module &M)    b LegacyPassManager.cpp:1680
for Manager in Managers:
    # 在本项目中 manager 只有一个,类型为 MPPassManager (Module Pass)
    Manager->runOnModule(M)
        # bool MPPassManager::runOnModule(Module &M)    b LegacyPassManager.cpp:1564
        for MP in Manager:
            # 此处运行 13 个 MP Pass
            MP->runOnModule(M)
                # MP 内部套着 FP
                for FP in MP:
                    # bool FPPassManager::runOnFunction(Function &F)    b LegacyPassManager.cpp:1502
                    pass

常用信息收集

LegacyPassManager.cpp:1579 ModulePass *MP

b LegacyPassManager.cpp:1714 void PassManager::add(Pass *P) 此处打断点可以看到 Pass 添加的过程

b LLVMTargetMachine.cpp:102 static MCContext *addPassesToGenerateCode(...) 添加 Pass 处

b HiVoyagerExpandLibCalls.cpp:391 llvm.memcpy 展开处

HiVoyagerTargetMachine.cpp Pass 添加处,此处可以禁用某些 Pass

HiVoyagerExpandLibCalls.cpp 仔细学习此文件,此处有 memcpy 的展开操作,涉及指令修改的 Pass

AsmWriter.cpp dump() 的实现在这里

SelectionDAG.cpp:737 PersistentId 在这里产生

Debug.cpp and LegacyPassManager.cpp -debug -print-after-all 参数在这里

mali_gfx_compiler.cpp 参数配置和编译入口在这里

cmpbe_bfr_backend_gles.c and cmpbe_bfr_backend_vulkan.c pass 注册位置

b SelectionDAG.cpp:737 if (N->PersistentId == 112) 节点创建处断点

b mali_gfx_compiler.cpp:611 编译入口

寄存器影响关系

bool isTypeLegal(EVT VT) const {

判断 TypeLegal:

assert(!VT.isSimple() ||
       (unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != nullptr;

} isTypeLegal 受到 RegClassForVT 影响 而 isTypeLegal 被 computeRegisterProperties 调用, computeRegisterProperties 函数内又会影响到 NumRegistersForVT、RegisterTypeForVT、TransformToType TransformToType 会影响到 LegalizeType() 这一个步骤

TD 文件

IntrinsicsAArch64.td -> build/compiler/llvm/include/llvm/IR/Intrinsics.gen 【TODO】

ytgui commented 5 years ago

llvm::cl::opt 不定参数构造函数

// 传入变参数
static cl::opt<bool> PrintAfterAll("print-after-all",
    llvm::cl::desc("Print IR after each pass"),
    cl::init(false));

// 内部传递变长参数
apply(this, Ms...);

// apply 实现,将变长参数递归传递下去
void apply(Opt *O, const Mod &M, const Mods &... Ms) {
  apply(O, Ms...);
}

// llvm::cl::Hidden
enum OptionHidden {   // Control whether -help shows this option
    NotHidden = 0x00,   // Option included in -help & -help-hidden
    Hidden = 0x01,      // -help doesn't, but -help-hidden does
    ReallyHidden = 0x02 // Neither -help nor -help-hidden show this arg
};
ytgui commented 5 years ago

LLVM data structure

include/llvm/ADT

https://github.com/FrozenGene/presentation/blob/master/pdf/LLVM.pdf

ytgui commented 5 years ago

Op 类型判断

Op.getValueType().isVector()

插入或替换一条 Node

  1. 原始 Op 的位置:SDLoc dl(Op);
  2. 原始 Op 的操作数:SDValue Input = Op.getOperand(1);
  3. 新建 Node:return DAG.getNode(ISD::FP_TO_UINT, dl, EVTType, Input);
  4. 如果有多个操作数,则 Inputs = {Op1, Op2} 构建出 vector 作为参数

创建 Call

IntrinsicInst *II = cast<IntrinsicInst>(&*I);
llvm::Function *F = llvm::Intrinsic::getDeclaration(M, II->getIntrinsicID(), II->getType());
SmallVector<Value *, 16> Ops;
for (unsigned j = 0; j < dynamicIndexPos; j += 1) {
    Ops.push_back(II->getOperand(j));
}
Ops.push_back(index_op);

auto output = Builder.CreateCall(F, Ops);
output->moveBefore(prevInst);

创建 / 替换 Node

unsigned EleNum = Op.getValueType().getVectorNumElements();
for(unsigned i = 0; i < EleNum; ++i) {
    SDValue E = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SeleTy, Input, DAG.getConstant(i, dl, MVT::i32));
    SDValue T = DAG.getNode(ISD::FP_TO_UINT, dl, TeleTy, E);
    Ops.push_back(T);
}
Ops.resize(EleNum);
return DAG.getNode(ISD::BUILD_VECTOR, dl, Op.getValueType(), Ops);

F 到 I 遍历,跳过 BB

for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
    if (!isa<IntrinsicInst>(&*I))
      continue;
    do_something();
}
ytgui commented 5 years ago

创建一个 IR 函数: http://www.llvmpy.org/llvmpy-doc/dev/doc/firstexample.html