Compare commits
1 Commits
deploy-202
...
midend-Fun
| Author | SHA1 | Date | |
|---|---|---|---|
| 97d83d733e |
@ -652,6 +652,13 @@ public:
|
||||
} ///< 移除指定位置的指令
|
||||
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
|
||||
|
||||
static void bbdfs(BasicBlock* bb, std::function<bool(BasicBlock*)> func) {
|
||||
if (func(bb))
|
||||
return;
|
||||
for (auto succ : bb->getSuccessors())
|
||||
bbdfs(succ, func);
|
||||
}
|
||||
|
||||
/// 清理基本块中的所有使用关系
|
||||
void cleanup();
|
||||
|
||||
@ -767,7 +774,7 @@ protected:
|
||||
: User(type, name), kind(kind), parent(parent) {}
|
||||
|
||||
public:
|
||||
|
||||
virtual Instruction* copy(std::function<Value*(Value*)> getValue) const = 0;
|
||||
public:
|
||||
Kind getKind() const { return kind; }
|
||||
std::string getKindString() const{
|
||||
@ -964,6 +971,18 @@ class PhiInst : public Instruction {
|
||||
}
|
||||
}
|
||||
|
||||
PhiInst(Type *type,
|
||||
const std::vector<std::pair<BasicBlock*, Value*>> IncomingValues,
|
||||
BasicBlock *parent = nullptr,
|
||||
const std::string &name = "")
|
||||
: Instruction(Kind::kPhi, type, parent, name), vsize(IncomingValues.size()) {
|
||||
for(size_t i = 0; i < vsize; ++i) {
|
||||
addOperand(IncomingValues[i].first);
|
||||
addOperand(IncomingValues[i].second);
|
||||
}
|
||||
refreshMap(); ///< 刷新块到值的映射关系
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned getNumIncomingValues() const { return vsize; } ///< 获取传入值的数量
|
||||
Value *getIncomingValue(unsigned Idx) const { return getOperand(Idx * 2); } ///< 获取指定位置的传入值
|
||||
@ -1013,6 +1032,7 @@ class PhiInst : public Instruction {
|
||||
} ///< 刷新块到值的映射关系
|
||||
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
};
|
||||
|
||||
|
||||
@ -1047,6 +1067,7 @@ protected:
|
||||
public:
|
||||
Value* getOperand() const { return User::getOperand(0); }
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
}; // class UnaryInst
|
||||
|
||||
//! Binary instruction, e.g., arithmatic, relation, logic, etc.
|
||||
@ -1126,6 +1147,7 @@ public:
|
||||
return new BinaryInst(kind, type, lhs, rhs, parent, name);
|
||||
}
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
}; // class BinaryInst
|
||||
|
||||
//! The return statement
|
||||
@ -1217,6 +1239,7 @@ public:
|
||||
return succs;
|
||||
}
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
}; // class CondBrInst
|
||||
|
||||
class UnreachableInst : public Instruction {
|
||||
@ -1225,6 +1248,7 @@ public:
|
||||
explicit UnreachableInst(const std::string& name, BasicBlock *parent = nullptr)
|
||||
: Instruction(kUnreachable, Type::getVoidType(), parent, "") {}
|
||||
void print(std::ostream& os) const { os << "unreachable"; }
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
};
|
||||
|
||||
//! Allocate memory for stack variables, used for non-global variable declartion
|
||||
@ -1243,6 +1267,7 @@ public:
|
||||
return getType()->as<PointerType>()->getBaseType();
|
||||
} ///< 获取分配的类型
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
}; // class AllocaInst
|
||||
|
||||
|
||||
@ -1281,6 +1306,7 @@ public:
|
||||
return new GetElementPtrInst(resultType, basePointer, indices, parent, name);
|
||||
}
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
};
|
||||
|
||||
//! Load a value from memory address specified by a pointer value
|
||||
@ -1299,6 +1325,7 @@ protected:
|
||||
public:
|
||||
Value* getPointer() const { return getOperand(0); }
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
}; // class LoadInst
|
||||
|
||||
//! Store a value to memory address specified by a pointer value
|
||||
@ -1318,6 +1345,7 @@ public:
|
||||
Value* getValue() const { return getOperand(0); }
|
||||
Value* getPointer() const { return getOperand(1); }
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
}; // class StoreInst
|
||||
|
||||
//! Memset instruction
|
||||
@ -1348,6 +1376,7 @@ public:
|
||||
Value* getSize() const { return getOperand(2); }
|
||||
Value* getValue() const { return getOperand(3); }
|
||||
void print(std::ostream& os) const override;
|
||||
Instruction* copy(std::function<Value*(Value*)> getValue) const override;
|
||||
};
|
||||
|
||||
class GlobalValue;
|
||||
@ -1385,19 +1414,11 @@ protected:
|
||||
public:
|
||||
using block_list = std::list<std::unique_ptr<BasicBlock>>;
|
||||
using arg_list = std::vector<Argument *>;
|
||||
enum FunctionAttribute : uint64_t {
|
||||
PlaceHolder = 0x0UL,
|
||||
Pure = 0x1UL << 0,
|
||||
SelfRecursive = 0x1UL << 1,
|
||||
SideEffect = 0x1UL << 2,
|
||||
NoPureCauseMemRead = 0x1UL << 3
|
||||
};
|
||||
|
||||
protected:
|
||||
Module *parent; ///< 函数的父模块
|
||||
block_list blocks; ///< 函数包含的基本块列表
|
||||
arg_list arguments; ///< 函数参数列表
|
||||
FunctionAttribute attribute = PlaceHolder; ///< 函数属性
|
||||
std::set<Function *> callees; ///< 函数调用的函数集合
|
||||
public:
|
||||
static unsigned getcloneIndex() {
|
||||
@ -1405,17 +1426,12 @@ protected:
|
||||
cloneIndex += 1;
|
||||
return cloneIndex - 1;
|
||||
}
|
||||
Function* clone(const std::string &suffix = "_" + std::to_string(getcloneIndex()) + "@") const;
|
||||
Function* copy_func();
|
||||
const std::set<Function *>& getCallees() { return callees; }
|
||||
void addCallee(Function *callee) { callees.insert(callee); }
|
||||
void removeCallee(Function *callee) { callees.erase(callee); }
|
||||
void clearCallees() { callees.clear(); }
|
||||
std::set<Function *> getCalleesWithNoExternalAndSelf();
|
||||
FunctionAttribute getAttribute() const { return attribute; }
|
||||
void setAttribute(FunctionAttribute attr) {
|
||||
attribute = static_cast<FunctionAttribute>(attribute | attr);
|
||||
}
|
||||
void clearAttribute() { attribute = PlaceHolder; }
|
||||
Type* getReturnType() const { return getType()->as<FunctionType>()->getReturnType(); }
|
||||
auto getParamTypes() const { return getType()->as<FunctionType>()->getParamTypes(); }
|
||||
auto getBasicBlocks() { return make_range(blocks); }
|
||||
|
||||
@ -652,6 +652,12 @@ void BasicBlock::print(std::ostream &os) const {
|
||||
}
|
||||
}
|
||||
|
||||
void Instruction::print(std::ostream &os) const {
|
||||
this->getType()->print(os);
|
||||
std::cerr << " %" << getName() << " ";
|
||||
return;
|
||||
}
|
||||
|
||||
void PhiInst::print(std::ostream &os) const {
|
||||
printVarName(os, this);
|
||||
os << " = " << getKindString() << " " << *getType() << " ";
|
||||
@ -1440,4 +1446,76 @@ void Argument::cleanup() {
|
||||
uses.clear();
|
||||
}
|
||||
|
||||
Function* Function::copy_func(){
|
||||
std::unordered_map<Value*, Value*> valueMap;
|
||||
// copy global
|
||||
for (auto &gvalue : parent->getGlobals()) {
|
||||
valueMap.emplace(gvalue.get(), gvalue.get());
|
||||
}
|
||||
// copy global const
|
||||
for (auto &cvalue : parent->getConsts()) {
|
||||
valueMap.emplace(cvalue.get(), cvalue.get());
|
||||
}
|
||||
|
||||
// copy function
|
||||
auto newFunc = new Function(parent, type, name + "_copy" + std::to_string(getcloneIndex()));
|
||||
// copy arg
|
||||
for(int i = 0; i < arguments.size(); i++) {
|
||||
auto arg = arguments[i];
|
||||
// Argument(paramActualTypes[i], function, i, paramNames[i]);
|
||||
auto newarg = new Argument(arg->getType(), newFunc, i, arg->getName() + "_copy");
|
||||
newFunc->insertArgument(newarg);
|
||||
valueMap[arg] = newarg;
|
||||
}
|
||||
//
|
||||
for (auto &bb : blocks) {
|
||||
BasicBlock* copybb = newFunc->addBasicBlock();
|
||||
valueMap.emplace(bb, copybb);
|
||||
}
|
||||
|
||||
for(auto &bb : blocks) {
|
||||
auto BB = bb.get();
|
||||
auto copybb = dynamic_cast<BasicBlock*>(valueMap[BB]);
|
||||
for(auto pred : BB->getPredecessors()) {
|
||||
copybb->addPredecessor(dynamic_cast<BasicBlock*>(valueMap[pred]));
|
||||
}
|
||||
for(auto succ : BB->getSuccessors()) {
|
||||
copybb->addSuccessor(dynamic_cast<BasicBlock*>(valueMap[succ]));
|
||||
}
|
||||
}
|
||||
|
||||
// if cant find, return itself
|
||||
auto getValue = [&](Value* val) -> Value* {
|
||||
if (val == nullptr) {
|
||||
std::cerr << "getValue(nullptr)" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
if (dynamic_cast<ConstantValue*>(val)) return val;
|
||||
if (auto iter = valueMap.find(val); iter != valueMap.end()) return iter->second;
|
||||
return val;
|
||||
};
|
||||
|
||||
std::set<BasicBlock*> visitedbb;
|
||||
|
||||
const auto copyBlock = [&](BasicBlock* bb) -> bool {
|
||||
if (visitedbb.count(bb)) return true;
|
||||
visitedbb.insert(bb);
|
||||
auto bbCpy = dynamic_cast<BasicBlock*>(valueMap.at(bb));
|
||||
for (auto &Inst : bb->getInstructions()) {
|
||||
auto inst = Inst.get();
|
||||
// inst->print(std::cerr);
|
||||
// std::cerr << std::endl;
|
||||
auto copyinst = inst->copy(getValue);
|
||||
copyinst->setParent(bbCpy);
|
||||
valueMap.emplace(inst, copyinst);
|
||||
bbCpy->instructions.emplace_back(copyinst);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
//dfs基本块将指令复制到新函数中
|
||||
BasicBlock::bbdfs(getEntryBlock(), copyBlock);
|
||||
|
||||
return newFunc;
|
||||
}
|
||||
|
||||
} // namespace sysy
|
||||
|
||||
Reference in New Issue
Block a user