提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
学习LLVM得第1章
一、与架构无关的SDNode的Opcode
LLVMIR--->SDNode
的过程中会涉及Opcode的转换,这里的Opcode是与架构无关的,即所有架构通用。
/source/llvm/include/llvm/IR/ Instruction.h
/source/llvm/include/llvm/IR/ Instruction.def //定义Opcode
//Instruction.h
class Instruction : public User,
public ilist_node_with_parent<Instruction, BasicBlock> {
// Exported enumerations.
enum TermOps { // These terminate basic blocks
#define FIRST_TERM_INST(N) TermOpsBegin = N,
#define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N,
#define LAST_TERM_INST(N) TermOpsEnd = N+1
#include "llvm/IR/Instruction.def"
};
enum UnaryOps {
#define FIRST_UNARY_INST(N) UnaryOpsBegin = N,
#define HANDLE_UNARY_INST(N, OPC, CLASS) OPC = N,
#define LAST_UNARY_INST(N) UnaryOpsEnd = N+1
#include "llvm/IR/Instruction.def"
};
enum BinaryOps {
#define FIRST_BINARY_INST(N) BinaryOpsBegin = N,
#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
#define LAST_BINARY_INST(N) BinaryOpsEnd = N+1
#include "llvm/IR/Instruction.def"
};
enum MemoryOps {
#define FIRST_MEMORY_INST(N) MemoryOpsBegin = N,
#define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N,
#define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1
#include "llvm/IR/Instruction.def"
};
enum CastOps {
#define FIRST_CAST_INST(N) CastOpsBegin = N,
#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N,
#define LAST_CAST_INST(N) CastOpsEnd = N+1
#include "llvm/IR/Instruction.def"
};
enum FuncletPadOps {
#define FIRST_FUNCLETPAD_INST(N) FuncletPadOpsBegin = N,
#define HANDLE_FUNCLETPAD_INST(N, OPC, CLASS) OPC = N,
#define LAST_FUNCLETPAD_INST(N) FuncletPadOpsEnd = N+1
#include "llvm/IR/Instruction.def"
};
enum OtherOps {
#define FIRST_OTHER_INST(N) OtherOpsBegin = N,
#define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N,
#define LAST_OTHER_INST(N) OtherOpsEnd = N+1
#include "llvm/IR/Instruction.def"
};
}
上文将Instruction的Opcode定义为7种类型。
Instruction类继承自User,所以指令的ID号有区别。这里引入了InstructionVal
Enum values starting at InstructionVal are used for Instructions;
用于界定
ID号大于InstructionVal
的才会被认为是指令。
指令的ID号请查看文件/source/llvm/include/llvm/IR/ Instruction.def
FIRST_TERM_INST ( 1)
HANDLE_TERM_INST ( 1, Ret , ReturnInst)
HANDLE_TERM_INST ( 2, Br , BranchInst)
HANDLE_TERM_INST ( 3, Switch , SwitchInst)
HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
HANDLE_TERM_INST ( 6, Resume , ResumeInst)
HANDLE_TERM_INST ( 7, Unreachable , UnreachableInst)
HANDLE_TERM_INST ( 8, CleanupRet , CleanupReturnInst)
HANDLE_TERM_INST ( 9, CatchRet , CatchReturnInst)
HANDLE_TERM_INST (10, CatchSwitch , CatchSwitchInst)
HANDLE_TERM_INST (11, CallBr , CallBrInst) // A call-site terminator
LAST_TERM_INST (11)
上问可知Ret指令的ID,即OpCode是1
。
1. 与架构相关的MachineNode的Opcode
SDNode--->MahineNode
的过程中会涉及Opcode的转换,架构Opcode相关的内容如下产生。
../build/bin/llvm-tblgen \
/[source]/llvm/lib/Target/RISCV/RISCV.td \
--gen-instr-info \
-I /[source]/llvm/include/ \
-I /[source]/lib/Target/RISCV/
#source请改为源码的地址
#本例子对的RISCV架构,其他架构请更换
输出与特定架构相关的文件。「这里涉及LLVM中的tblgen以及模块化概念,对于新架构添加和修改很重要。本文重点不在于此,有机会再做讲解。」
也可以在build目录中的build/lib/Target/AArch64
相关Instruction.inc
文件中找到上述生成内容。
2.读入数据
LLVMIR
代码如下(示例):
class Instruction : public User,
public ilist_node_with_parent<Instruction, BasicBlock> {
BasicBlock *Parent;
DebugLoc DbgLoc; // 'dbg' Metadata cache.
/// Relative order of this instruction in its parent basic block. Used for
/// O(1) local dominance checks between instructions.
mutable unsigned Order = 0;
/// Returns a member of one of the enums like Instruction::Add.
unsigned getOpcode() const { return getValueID() - InstructionVal; }
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
/// Set the debug location information for this instruction.
void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
/// Return the debug location for this node as a DebugLoc.
const DebugLoc &getDebugLoc() const { return DbgLoc; }
unsigned getOpcode() const { return getValueID() - InstructionVal; }
中getValueID()是class Value
的成员。
SelectionDAGBuilder
class SelectionDAGBuilder {
/// The current instruction being visited.
const Instruction *CurInst = nullptr;
DenseMap<const Value*, SDValue> NodeMap;
Value SDValue
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。