[midend-llvmirprint]实现了大部分函数的print方法,TODO:需要完善func和module的print方法以及重命名的逻辑

This commit is contained in:
rain2133
2025-08-06 01:02:11 +08:00
parent 5f63554ca3
commit 08fcda939b
2 changed files with 378 additions and 61 deletions

View File

@@ -83,6 +83,7 @@ class Type {
auto as() const -> std::enable_if_t<std::is_base_of_v<Type, T>, T *> { auto as() const -> std::enable_if_t<std::is_base_of_v<Type, T>, T *> {
return dynamic_cast<T *>(const_cast<Type *>(this)); return dynamic_cast<T *>(const_cast<Type *>(this));
} }
virtual void print(std::ostream& os) const;
}; };
class PointerType : public Type { class PointerType : public Type {
@@ -97,6 +98,7 @@ class PointerType : public Type {
public: public:
Type* getBaseType() const { return baseType; } ///< 获取指向的类型 Type* getBaseType() const { return baseType; } ///< 获取指向的类型
void print(std::ostream& os) const override;
}; };
class FunctionType : public Type { class FunctionType : public Type {
@@ -116,6 +118,7 @@ class FunctionType : public Type {
Type* getReturnType() const { return returnType; } ///< 获取返回值类信息 Type* getReturnType() const { return returnType; } ///< 获取返回值类信息
auto getParamTypes() const { return make_range(paramTypes); } ///< 获取形参类型列表 auto getParamTypes() const { return make_range(paramTypes); } ///< 获取形参类型列表
unsigned getNumParams() const { return paramTypes.size(); } ///< 获取形参数量 unsigned getNumParams() const { return paramTypes.size(); } ///< 获取形参数量
void print(std::ostream& os) const override;
}; };
class ArrayType : public Type { class ArrayType : public Type {
@@ -132,6 +135,7 @@ class ArrayType : public Type {
: Type(Kind::kArray), elementType(elementType), numElements(numElements) {} : Type(Kind::kArray), elementType(elementType), numElements(numElements) {}
Type *elementType; Type *elementType;
unsigned numElements; // 当前维度的大小 unsigned numElements; // 当前维度的大小
void print(std::ostream& os) const override;
}; };
/*! /*!
@@ -206,6 +210,7 @@ class Use {
User* getUser() const { return user; } ///< 返回使用者 User* getUser() const { return user; } ///< 返回使用者
Value* getValue() const { return value; } ///< 返回被使用的值 Value* getValue() const { return value; } ///< 返回被使用的值
void setValue(Value *newValue) { value = newValue; } ///< 将被使用的值设置为newValue void setValue(Value *newValue) { value = newValue; } ///< 将被使用的值设置为newValue
void print(std::ostream& os) const;
}; };
//! The base class of all value types //! The base class of all value types
@@ -238,6 +243,7 @@ class Value {
uses.remove(use); uses.remove(use);
} ///< 删除使用关系use } ///< 删除使用关系use
void removeAllUses(); void removeAllUses();
virtual void print(std::ostream& os) const = 0; ///< 输出值信息到输出流
}; };
/** /**
@@ -402,6 +408,7 @@ public:
virtual bool isZero() const = 0; virtual bool isZero() const = 0;
virtual bool isOne() const = 0; virtual bool isOne() const = 0;
void print(std::ostream& os) const = 0;
}; };
class ConstantInteger : public ConstantValue { class ConstantInteger : public ConstantValue {
@@ -428,6 +435,7 @@ public:
bool isZero() const override { return constVal == 0; } bool isZero() const override { return constVal == 0; }
bool isOne() const override { return constVal == 1; } bool isOne() const override { return constVal == 1; }
void print(std::ostream& os) const;
}; };
class ConstantFloating : public ConstantValue { class ConstantFloating : public ConstantValue {
@@ -454,6 +462,7 @@ public:
bool isZero() const override { return constFVal == 0.0f; } bool isZero() const override { return constFVal == 0.0f; }
bool isOne() const override { return constFVal == 1.0f; } bool isOne() const override { return constFVal == 1.0f; }
void print(std::ostream& os) const;
}; };
class UndefinedValue : public ConstantValue { class UndefinedValue : public ConstantValue {
@@ -485,6 +494,7 @@ public:
bool isZero() const override { return false; } bool isZero() const override { return false; }
bool isOne() const override { return false; } bool isOne() const override { return false; }
void print(std::ostream& os) const;
}; };
// --- End of refactored ConstantValue and related classes --- // --- End of refactored ConstantValue and related classes ---
@@ -625,6 +635,7 @@ public:
} }
} ///< 移除指定位置的指令 } ///< 移除指定位置的指令
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block); iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
void print(std::ostream& os) const;
}; };
//! User is the abstract base type of `Value` types which use other `Value` as //! User is the abstract base type of `Value` types which use other `Value` as
@@ -736,57 +747,57 @@ public:
std::string getKindString() const{ std::string getKindString() const{
switch (kind) { switch (kind) {
case kInvalid: case kInvalid:
return "Invalid"; return "invalid";
case kAdd: case kAdd:
return "Add"; return "add";
case kSub: case kSub:
return "Sub"; return "sub";
case kMul: case kMul:
return "Mul"; return "mul";
case kDiv: case kDiv:
return "Div"; return "sdiv";
case kRem: case kRem:
return "Rem"; return "srem";
case kICmpEQ: case kICmpEQ:
return "ICmpEQ"; return "icmp eq";
case kICmpNE: case kICmpNE:
return "ICmpNE"; return "icmp ne";
case kICmpLT: case kICmpLT:
return "ICmpLT"; return "icmp slt";
case kICmpGT: case kICmpGT:
return "ICmpGT"; return "icmp sgt";
case kICmpLE: case kICmpLE:
return "ICmpLE"; return "icmp sle";
case kICmpGE: case kICmpGE:
return "ICmpGE"; return "icmp sge";
case kFAdd: case kFAdd:
return "FAdd"; return "fadd";
case kFSub: case kFSub:
return "FSub"; return "fsub";
case kFMul: case kFMul:
return "FMul"; return "fmul";
case kFDiv: case kFDiv:
return "FDiv"; return "fdiv";
case kFCmpEQ: case kFCmpEQ:
return "FCmpEQ"; return "fcmp oeq";
case kFCmpNE: case kFCmpNE:
return "FCmpNE"; return "fcmp one";
case kFCmpLT: case kFCmpLT:
return "FCmpLT"; return "fcmp olt";
case kFCmpGT: case kFCmpGT:
return "FCmpGT"; return "fcmp ogt";
case kFCmpLE: case kFCmpLE:
return "FCmpLE"; return "fcmp ole";
case kFCmpGE: case kFCmpGE:
return "FCmpGE"; return "fcmp oge";
case kAnd: case kAnd:
return "And"; return "and";
case kOr: case kOr:
return "Or"; return "or";
case kNeg: case kNeg:
return "Neg"; return "neg";
case kNot: case kNot:
return "Not"; return "not";
case kFNeg: case kFNeg:
return "FNeg"; return "FNeg";
case kFNot: case kFNot:
@@ -794,27 +805,29 @@ public:
case kFtoI: case kFtoI:
return "FtoI"; return "FtoI";
case kItoF: case kItoF:
return "IToF"; return "iToF";
case kCall: case kCall:
return "Call"; return "call";
case kCondBr: case kCondBr:
return "CondBr"; return "condBr";
case kBr: case kBr:
return "Br"; return "br";
case kReturn: case kReturn:
return "Return"; return "return";
case kUnreachable:
return "unreachable";
case kAlloca: case kAlloca:
return "Alloca"; return "alloca";
case kLoad: case kLoad:
return "Load"; return "load";
case kStore: case kStore:
return "Store"; return "store";
case kGetElementPtr: case kGetElementPtr:
return "GetElementPtr"; return "getElementPtr";
case kMemset: case kMemset:
return "Memset"; return "memset";
case kPhi: case kPhi:
return "Phi"; return "phi";
case kBitItoF: case kBitItoF:
return "BitItoF"; return "BitItoF";
case kBitFtoI: case kBitFtoI:
@@ -887,6 +900,7 @@ public:
static constexpr uint64_t DefineOpMask = kAlloca | kStore | kPhi; static constexpr uint64_t DefineOpMask = kAlloca | kStore | kPhi;
return (kind & DefineOpMask) != 0U; return (kind & DefineOpMask) != 0U;
} }
virtual void print(std::ostream& os) const = 0;
}; // class Instruction }; // class Instruction
class Function; class Function;
@@ -957,6 +971,7 @@ class PhiInst : public Instruction {
} }
} ///< 刷新块到值的映射关系 } ///< 刷新块到值的映射关系
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); } auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
void print(std::ostream& os) const override;
}; };
@@ -965,16 +980,20 @@ class CallInst : public Instruction {
friend class IRBuilder; friend class IRBuilder;
protected: protected:
CallInst(Function *callee, const std::vector<Value *> &args = {}, CallInst(Function *callee, const std::vector<Value *> &args, BasicBlock *parent = nullptr, const std::string &name = "")
BasicBlock *parent = nullptr, const std::string &name = ""); : Instruction(kCall, callee->getReturnType(), parent, name) {
addOperand(callee);
for (auto arg : args) {
addOperand(arg);
}
}
public: public:
Function* getCallee() const; Function *getCallee() const { return dynamic_cast<Function *>(getOperand(0)); }
auto getArguments() const { auto getArguments() const {
return make_range(std::next(operand_begin()), operand_end()); return make_range(std::next(operand_begin()), operand_end());
} }
void print(std::ostream& os) const override;
}; // class CallInst }; // class CallInst
//! Unary instruction, includes '!', '-' and type conversion. //! Unary instruction, includes '!', '-' and type conversion.
@@ -992,7 +1011,7 @@ protected:
public: public:
Value* getOperand() const { return User::getOperand(0); } Value* getOperand() const { return User::getOperand(0); }
void print(std::ostream& os) const override;
}; // class UnaryInst }; // class UnaryInst
//! Binary instruction, e.g., arithmatic, relation, logic, etc. //! Binary instruction, e.g., arithmatic, relation, logic, etc.
@@ -1071,6 +1090,7 @@ public:
// 后端处理数组访存操作时需要创建计算地址的指令,需要在外部构造 BinaryInst 对象 // 后端处理数组访存操作时需要创建计算地址的指令,需要在外部构造 BinaryInst 对象
return new BinaryInst(kind, type, lhs, rhs, parent, name); return new BinaryInst(kind, type, lhs, rhs, parent, name);
} }
void print(std::ostream& os) const override;
}; // class BinaryInst }; // class BinaryInst
//! The return statement //! The return statement
@@ -1091,6 +1111,7 @@ class ReturnInst : public Instruction {
Value* getReturnValue() const { Value* getReturnValue() const {
return hasReturnValue() ? getOperand(0) : nullptr; return hasReturnValue() ? getOperand(0) : nullptr;
} }
void print(std::ostream& os) const override;
}; };
//! Unconditional branch //! Unconditional branch
@@ -1120,7 +1141,7 @@ public:
} }
return succs; return succs;
} }
void print(std::ostream& os) const override;
}; // class UncondBrInst }; // class UncondBrInst
//! Conditional branch //! Conditional branch
@@ -1160,7 +1181,7 @@ public:
} }
return succs; return succs;
} }
void print(std::ostream& os) const override;
}; // class CondBrInst }; // class CondBrInst
class UnreachableInst : public Instruction { class UnreachableInst : public Instruction {
@@ -1168,7 +1189,7 @@ public:
// 构造函数:设置指令类型为 kUnreachable // 构造函数:设置指令类型为 kUnreachable
explicit UnreachableInst(const std::string& name, BasicBlock *parent = nullptr) explicit UnreachableInst(const std::string& name, BasicBlock *parent = nullptr)
: Instruction(kUnreachable, Type::getVoidType(), parent, "") {} : Instruction(kUnreachable, Type::getVoidType(), parent, "") {}
void print(std::ostream& os) const { os << "unreachable"; }
}; };
//! Allocate memory for stack variables, used for non-global variable declartion //! Allocate memory for stack variables, used for non-global variable declartion
@@ -1186,7 +1207,7 @@ public:
Type* getAllocatedType() const { Type* getAllocatedType() const {
return getType()->as<PointerType>()->getBaseType(); return getType()->as<PointerType>()->getBaseType();
} ///< 获取分配的类型 } ///< 获取分配的类型
void print(std::ostream& os) const override;
}; // class AllocaInst }; // class AllocaInst
@@ -1224,6 +1245,7 @@ public:
BasicBlock *parent = nullptr, const std::string &name = "") { BasicBlock *parent = nullptr, const std::string &name = "") {
return new GetElementPtrInst(resultType, basePointer, indices, parent, name); return new GetElementPtrInst(resultType, basePointer, indices, parent, name);
} }
void print(std::ostream& os) const override;
}; };
//! Load a value from memory address specified by a pointer value //! Load a value from memory address specified by a pointer value
@@ -1241,7 +1263,7 @@ protected:
public: public:
Value* getPointer() const { return getOperand(0); } Value* getPointer() const { return getOperand(0); }
void print(std::ostream& os) const override;
}; // class LoadInst }; // class LoadInst
//! Store a value to memory address specified by a pointer value //! Store a value to memory address specified by a pointer value
@@ -1260,7 +1282,7 @@ protected:
public: public:
Value* getValue() const { return getOperand(0); } Value* getValue() const { return getOperand(0); }
Value* getPointer() const { return getOperand(1); } Value* getPointer() const { return getOperand(1); }
void print(std::ostream& os) const override;
}; // class StoreInst }; // class StoreInst
//! Memset instruction //! Memset instruction
@@ -1290,7 +1312,7 @@ public:
Value* getBegin() const { return getOperand(1); } Value* getBegin() const { return getOperand(1); }
Value* getSize() const { return getOperand(2); } Value* getSize() const { return getOperand(2); }
Value* getValue() const { return getOperand(3); } Value* getValue() const { return getOperand(3); }
void print(std::ostream& os) const override;
}; };
class GlobalValue; class GlobalValue;
@@ -1308,6 +1330,7 @@ public:
public: public:
Function* getParent() const { return func; } Function* getParent() const { return func; }
int getIndex() const { return index; } int getIndex() const { return index; }
void print(std::ostream& os) const;
}; };
@@ -1385,6 +1408,7 @@ protected:
blocks.emplace_front(block); blocks.emplace_front(block);
return block; return block;
} }
void print(std::ostream& os) const;
}; };
//! Global value declared at file scope //! Global value declared at file scope
@@ -1450,6 +1474,7 @@ public:
return getByIndex(index); return getByIndex(index);
} ///< 通过多维索引indices获取初始值 } ///< 通过多维索引indices获取初始值
const ValueCounter& getInitValues() const { return initValues; } const ValueCounter& getInitValues() const { return initValues; }
void print(std::ostream& os) const;
}; // class GlobalValue }; // class GlobalValue
@@ -1507,6 +1532,8 @@ class ConstantVariable : public Value {
return getByIndex(index); return getByIndex(index);
} ///< 通过多维索引indices获取初始值 } ///< 通过多维索引indices获取初始值
const ValueCounter& getInitValues() const { return initValues; } ///< 获取初始值 const ValueCounter& getInitValues() const { return initValues; } ///< 获取初始值
void print(std::ostream& os) const;
void print_init(std::ostream& os) const;
}; };
using SymbolTableNode = struct SymbolTableNode { using SymbolTableNode = struct SymbolTableNode {
@@ -1620,6 +1647,8 @@ class Module {
void leaveScope() { variableTable.leaveScope(); } ///< 离开作用域 void leaveScope() { variableTable.leaveScope(); } ///< 离开作用域
bool isInGlobalArea() const { return variableTable.isInGlobalScope(); } ///< 是否位于全局作用域 bool isInGlobalArea() const { return variableTable.isInGlobalScope(); } ///< 是否位于全局作用域
void print(std::ostream& os) const;
}; };
/*! /*!

View File

@@ -5,9 +5,11 @@
#include <queue> #include <queue>
#include <set> #include <set>
#include <sstream> #include <sstream>
#include <iomanip>
#include <vector> #include <vector>
#include "IRBuilder.h" #include "IRBuilder.h"
using namespace std;
/** /**
* @file IR.cpp * @file IR.cpp
* *
@@ -15,6 +17,64 @@
*/ */
namespace sysy { namespace sysy {
/*相关打印函数*/
template <typename T>
ostream &interleave(std::ostream &os, const T &container, const std::string sep = ", ") {
auto b = container.begin(), e = container.end();
if (b == e)
return os;
os << *b;
for (b = std::next(b); b != e; b = std::next(b))
os << sep << *b;
return os;
}
template <typename T>
ostream &interleave_call(std::ostream &os, const T &container, const std::string sep = ", ") {
auto b = container.begin(), e = container.end();
b = std::next(b); // Skip the first element
if (b == e)
return os;
os << *b;
for (b = std::next(b); b != e; b = std::next(b))
os << sep << *b;
return os;
}
static inline ostream &printVarName(ostream &os, const Value *var)
{
if (dynamic_cast<const GlobalValue*>(var) != nullptr) {
auto globalVal = dynamic_cast<const GlobalValue*>(var);
return os << "@" << globalVal->getName();
} else {
return os << "%" << var->getName();
}
}
static inline ostream &printBlockName(ostream &os, const BasicBlock *block) {
return os << block->getName();
}
static inline ostream &printFunctionName(ostream &os, const Function *fn) {
return os << '@' << fn->getName();
}
static inline ostream &printOperand(ostream &os, const Value *value) {
auto constValue = dynamic_cast<const ConstantValue*>(value);
if (constValue != nullptr) {
constValue->print(os);
return os;
}
return printVarName(os, value);
}
inline std::ostream& operator<<(std::ostream& os, const Type& type) {
type.print(os);
return os;
}
inline std::ostream& operator<<(std::ostream& os, const Value& value) {
value.print(os);
return os;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Types // Types
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -73,6 +133,37 @@ auto Type::getSize() const -> unsigned {
return 0; return 0;
} }
void Type::print(ostream &os) const {
auto kind = getKind();
switch (kind){
case kInt: os << "i32"; break;
case kFloat: os << "float"; break;
case kVoid: os << "void"; break;
case kPointer:
static_cast<const PointerType *>(this)->getBaseType()->print(os);
os << "*";
break;
case kFunction:
static_cast<const FunctionType *>(this)->getReturnType()->print(os);
os << "(";
interleave(os, static_cast<const FunctionType *>(this)->getParamTypes());
os << ")";
break;
case kArray:
os << "[";
os << static_cast<const ArrayType *>(this)->getNumElements();
os << " x ";
static_cast<const ArrayType *>(this)->getElementType()->print(os);
os << "]";
break;
case kLabel:
default:
cerr << "error type\n";
break;
}
}
PointerType* PointerType::get(Type *baseType) { PointerType* PointerType::get(Type *baseType) {
static std::map<Type *, std::unique_ptr<PointerType>> pointerTypes; static std::map<Type *, std::unique_ptr<PointerType>> pointerTypes;
auto iter = pointerTypes.find(baseType); auto iter = pointerTypes.find(baseType);
@@ -204,6 +295,214 @@ UndefinedValue* UndefinedValue::get(Type* type) {
return newUndef; return newUndef;
} }
inline std::string getMachineCode(float fval) {
uint32_t mrf = *reinterpret_cast<uint32_t*>(&fval);
std::stringstream ss;
ss << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << mrf;
return "0x" + ss.str();
}
void ConstantValue::print(std::ostream &os) const {
if(dynamic_cast<const ConstantInteger*>(this)) {
dynamic_cast<const ConstantInteger*>(this)->print(os);
} else if(dynamic_cast<const ConstantFloating*>(this)) {
dynamic_cast<const ConstantFloating*>(this)->print(os);
} else if(dynamic_cast<const UndefinedValue*>(this)) {
dynamic_cast<const UndefinedValue*>(this)->print(os);
} else {
os << "unknown constant type";
}
}
void ConstantInteger::print(std::ostream &os) const {
os << "i32 " << this->getInt();
}
void ConstantFloating::print(std::ostream &os) const {
os << "float " << getMachineCode(this->getFloat());
}
void UndefinedValue::print(std::ostream &os) const {
os << this->getType() << " undef";
}
void BasicBlock::print(std::ostream &os) const {
assert(this->getName() != "" && "BasicBlock name cannot be empty");
os << " ";
printBlockName(os, this);
os << ":\n";
for (auto &inst : instructions) {
os << " " << *inst << '\n';
}
}
void PhiInst::print(std::ostream &os) const {
printVarName(os, this);
os << " = " << getKindString() << " " << *getType() << " ";
for (unsigned i = 0; i < vsize; ++i) {
if (i > 0) {
os << ", ";
}
os << " [";
printOperand(os, getIncomingValue(i));
os << ", ";
printBlockName(os, getIncomingBlock(i));
os << "]";
}
}
void CallInst::print(std::ostream &os) const {
if(!getType()->isVoid()) {
printVarName(os, this) << " = ";
}
os << getKindString() << *getType() << " " ;
printFunctionName(os, getCallee());
os << "(";
interleave_call(os, getOperands());
os << ")";
}
// 情况比较复杂就不用getkindstring了
void UnaryInst::print(std::ostream &os) const {
printVarName(os, this) << " = ";
switch (getKind()) {
case kNeg:
os << "sub i32 0, ";
printOperand(os, getOperand());
break;
case kFNeg:
os << "fsub float 0.0, ";
printOperand(os, getOperand());
break;
case kNot:
os << "xor " << *getOperand()->getType() << " ";
printOperand(os, getOperand());
os << ", -1";
return;
case kFNot:
os << "fcmp une " << *getOperand()->getType() << " ";
printOperand(os, getOperand());
os << ", 0.0";
return;
case kFtoI:
os << "fptosi " << *getOperand()->getType() << " ";
printOperand(os, getOperand());
os << " to " << *getType();
return;
case kItoF:
os << "sitofp " << *getOperand()->getType() << " ";
printOperand(os, getOperand());
os << " to " << *getType();
return;
default:
os << "error unary inst";
return;
}
}
void AllocaInst::print(std::ostream &os) const {
PointerType *ptrType = dynamic_cast<PointerType *>(getType());
Type *baseType = ptrType->getBaseType();
printVarName(os, this);
os << " = " << getKindString() << " " << *baseType;
}
void BinaryInst::print(std::ostream &os) const {
printVarName(os, this) << " = ";
auto kind = getKind();
// 检查是否为比较指令
if (kind == kICmpEQ || kind == kICmpNE || kind == kICmpLT ||
kind == kICmpGT || kind == kICmpLE || kind == kICmpGE) {
// 整数比较指令
os << getKindString() << " " << *getLhs()->getType() << " ";
printOperand(os, getLhs());
os << ", ";
printOperand(os, getRhs());
} else if (kind == kFCmpEQ || kind == kFCmpNE || kind == kFCmpLT ||
kind == kFCmpGT || kind == kFCmpLE || kind == kFCmpGE) {
// 浮点比较指令
os << getKindString() << " " << *getLhs()->getType() << " ";
printOperand(os, getLhs());
os << ", ";
printOperand(os, getRhs());
} else {
// 算术和逻辑指令
os << getKindString() << " " << *getType() << " ";
printOperand(os, getLhs());
os << ", ";
printOperand(os, getRhs());
}
}
void ReturnInst::print(std::ostream &os) const {
os << "ret ";
if (hasReturnValue()) {
os << *getReturnValue()->getType() << " ";
printOperand(os, getReturnValue());
} else {
os << "void";
}
}
void UncondBrInst::print(std::ostream &os) const {
os << "br label %";
printBlockName(os, getBlock());
}
void CondBrInst::print(std::ostream &os) const {
os << "br " << *getCondition()->getType() << " ";
printOperand(os, getCondition());
os << ", label %";
printBlockName(os, getThenBlock());
os << ", label %";
printBlockName(os, getElseBlock());
}
void GetElementPtrInst::print(std::ostream &os) const {
printVarName(os, this) << " = getelementptr ";
// 获取基指针的基类型
auto basePtr = getBasePointer();
auto basePtrType = basePtr->getType()->as<PointerType>();
auto baseType = basePtrType->getBaseType();
os << *baseType << ", " << *basePtr->getType() << " ";
printOperand(os, basePtr);
// 打印索引 - 使用getIndex方法而不是getIndices
for (unsigned i = 0; i < getNumIndices(); ++i) {
auto index = getIndex(i);
os << ", " << *index->getType() << " ";
printOperand(os, index);
}
}
void LoadInst::print(std::ostream &os) const {
printVarName(os, this) << " = load " << *getType() << ", " << *getPointer()->getType() << " ";
printOperand(os, getPointer());
}
void MemsetInst::print(std::ostream &os) const {
os << "call void @llvm.memset.p0i8.i32(i8* ";
printOperand(os, getPointer());
os << ", i8 ";
printOperand(os, getOperand(3)); // value
os << ", i32 ";
printOperand(os, getOperand(2)); // size
os << ", i1 false)";
}
void StoreInst::print(std::ostream &os) const {
os << "store " << *getValue()->getType() << " ";
printOperand(os, getValue());
os << ", " << *getPointer()->getType() << " ";
printOperand(os, getPointer());
}
auto Function::getCalleesWithNoExternalAndSelf() -> std::set<Function *> { auto Function::getCalleesWithNoExternalAndSelf() -> std::set<Function *> {
std::set<Function *> result; std::set<Function *> result;
@@ -389,17 +688,6 @@ void PhiInst::replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock, V
addIncoming(newValue, newBlock); addIncoming(newValue, newBlock);
} }
CallInst::CallInst(Function *callee, const std::vector<Value *> &args, BasicBlock *parent, const std::string &name)
: Instruction(kCall, callee->getReturnType(), parent, name) {
addOperand(callee);
for (auto arg : args) {
addOperand(arg);
}
}
/**
* 获取被调用函数的指针
*/
Function * CallInst::getCallee() const { return dynamic_cast<Function *>(getOperand(0)); }
/** /**
* 获取变量指针 * 获取变量指针