[midend]修改GEP指令定义,更靠近llvm ir设计,增加自动推断类型函数,修复generator中错误生成ir的逻辑
This commit is contained in:
@@ -1124,24 +1124,24 @@ public:
|
||||
|
||||
|
||||
class GetElementPtrInst : public Instruction {
|
||||
friend class IRBuilder; // 如果您有IRBuilder来创建指令,需要friend
|
||||
friend class IRBuilder;
|
||||
|
||||
protected:
|
||||
// GEP的构造函数:
|
||||
// resultType: GEP计算出的地址的类型 (通常是指向目标元素类型的指针)
|
||||
// basePointer: 基指针 (第一个操作数)
|
||||
// indices: 索引列表 (后续操作数)
|
||||
GetElementPtrInst(Value *basePointer,
|
||||
const std::vector<Value *> &indices = {},
|
||||
BasicBlock *parent = nullptr, const std::string &name = "")
|
||||
: Instruction(Kind::kGetElementPtr, basePointer->getType(), parent, name) {
|
||||
GetElementPtrInst(Type *resultType,
|
||||
Value *basePointer,
|
||||
const std::vector<Value *> &indices = {},
|
||||
BasicBlock *parent = nullptr, const std::string &name = "")
|
||||
: Instruction(Kind::kGetElementPtr, resultType, parent, name) {
|
||||
assert(basePointer && "GEP base pointer cannot be null!");
|
||||
// TODO : 安全检查
|
||||
assert(basePointer->getType()->isPointer() );
|
||||
addOperand(basePointer); // 第一个操作数是基指针
|
||||
addOperands(indices); // 随后的操作数是索引
|
||||
}
|
||||
|
||||
public:
|
||||
Value* getBasePointer() const { return getOperand(0); }
|
||||
unsigned getNumIndices() const { return getNumOperands() - 1; }
|
||||
@@ -1155,7 +1155,7 @@ public:
|
||||
static GetElementPtrInst* create(Type *resultType, Value *basePointer,
|
||||
const std::vector<Value *> &indices = {},
|
||||
BasicBlock *parent = nullptr, const std::string &name = "") {
|
||||
return new GetElementPtrInst(basePointer, indices, parent, name);
|
||||
return new GetElementPtrInst(resultType, basePointer, indices, parent, name);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -294,15 +294,41 @@ class IRBuilder {
|
||||
return inst;
|
||||
} ///< 创建store指令
|
||||
PhiInst * createPhiInst(Type *type, const std::vector<Value*> &vals = {}, const std::vector<BasicBlock*> &blks = {}, const std::string &name = "") {
|
||||
auto predNum = block->getNumPredecessors();
|
||||
auto inst = new PhiInst(type, vals, blks, block, name);
|
||||
assert(inst);
|
||||
block->getInstructions().emplace(block->begin(), inst);
|
||||
return inst;
|
||||
} ///< 创建Phi指令
|
||||
GetElementPtrInst* createGetElementPtrInst(Value *basePointer,
|
||||
const std::vector<Value *> &indices = {},
|
||||
const std::string &name = "") {
|
||||
// GetElementPtrInst* createGetElementPtrInst(Value *basePointer,
|
||||
// const std::vector<Value *> &indices = {},
|
||||
// const std::string &name = "") {
|
||||
// std::string newName;
|
||||
// if (name.empty()) {
|
||||
// std::stringstream ss;
|
||||
// ss << tmpIndex;
|
||||
// newName = ss.str();
|
||||
// tmpIndex++;
|
||||
// } else {
|
||||
// newName = name;
|
||||
// }
|
||||
|
||||
// auto inst = new GetElementPtrInst(basePointer, indices, block, newName);
|
||||
// assert(inst);
|
||||
// block->getInstructions().emplace(position, inst);
|
||||
// return inst;
|
||||
// }
|
||||
/**
|
||||
* @brief 根据 LLVM 设计模式创建 GEP 指令。
|
||||
* 它会自动推断返回类型,无需手动指定。
|
||||
*/
|
||||
GetElementPtrInst *createGetElementPtrInst(Value *basePointer, const std::vector<Value *> &indices,
|
||||
const std::string &name = "") {
|
||||
Type *ResultElementType = getIndexedType(basePointer->getType(), indices);
|
||||
if (!ResultElementType) {
|
||||
assert(false && "Invalid GEP indexing!");
|
||||
return nullptr;
|
||||
}
|
||||
Type *ResultType = PointerType::get(ResultElementType);
|
||||
std::string newName;
|
||||
if (name.empty()) {
|
||||
std::stringstream ss;
|
||||
@@ -313,11 +339,31 @@ class IRBuilder {
|
||||
newName = name;
|
||||
}
|
||||
|
||||
auto inst = new GetElementPtrInst(basePointer, indices, block, newName);
|
||||
auto inst = new GetElementPtrInst(ResultType, basePointer, indices, block, newName);
|
||||
assert(inst);
|
||||
block->getInstructions().emplace(position, inst);
|
||||
return inst;
|
||||
}
|
||||
|
||||
static Type *getIndexedType(Type *pointerType, const std::vector<Value *> &indices) {
|
||||
assert(pointerType->isPointer() && "base must be a pointer type!");
|
||||
Type *CurrentType = pointerType;
|
||||
// 遍历所有索引来深入类型层次结构Sysy只支持数组
|
||||
for (int i = 0; i < indices.size(); ++i) {
|
||||
if(i == 0) {
|
||||
// 第一个索引是指针类型的元素类型
|
||||
CurrentType = pointerType->as<PointerType>()->getBaseType();
|
||||
} else
|
||||
if (CurrentType->isArray()) {
|
||||
CurrentType = CurrentType->as<ArrayType>()->getElementType();
|
||||
}
|
||||
else {
|
||||
// 如果类型不是聚合类型但仍有索引,说明索引过多,这是错误的
|
||||
CurrentType = nullptr;
|
||||
}
|
||||
}
|
||||
return CurrentType;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
|
||||
Reference in New Issue
Block a user