[IR]修复IR报错,调整结构。
This commit is contained in:
62
src/IR.cpp
62
src/IR.cpp
@@ -102,30 +102,54 @@ void Value::replaceAllUsesWith(Value *value) {
|
|||||||
uses.clear();
|
uses.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantValue* ConstantValue::get(int value) {
|
|
||||||
static std::map<int, std::unique_ptr<ConstantValue>> intConstants;
|
// Implementations for static members
|
||||||
auto iter = intConstants.find(value);
|
|
||||||
if (iter != intConstants.end()) {
|
std::unordered_map<ConstantValueKey, ConstantValue*, ConstantValueHash, ConstantValueEqual> ConstantValue::mConstantPool;
|
||||||
return iter->second.get();
|
std::unordered_map<Type*, UndefinedValue*> UndefinedValue::UndefValues;
|
||||||
|
|
||||||
|
ConstantValue* ConstantValue::get(Type* type, ConstantValVariant val) {
|
||||||
|
ConstantValueKey key = {type, val};
|
||||||
|
auto it = mConstantPool.find(key);
|
||||||
|
if (it != mConstantPool.end()) {
|
||||||
|
return it->second;
|
||||||
}
|
}
|
||||||
auto inst = new ConstantValue(value);
|
|
||||||
assert(inst);
|
ConstantValue* newConstant = nullptr;
|
||||||
auto result = intConstants.emplace(value, inst);
|
if (std::holds_alternative<int>(val)) {
|
||||||
return result.first->second.get();
|
newConstant = new ConstantInteger(type, std::get<int>(val));
|
||||||
|
} else if (std::holds_alternative<float>(val)) {
|
||||||
|
newConstant = new ConstantFloating(type, std::get<float>(val));
|
||||||
|
} else {
|
||||||
|
assert(false && "Unsupported ConstantValVariant type");
|
||||||
|
}
|
||||||
|
|
||||||
|
mConstantPool[key] = newConstant;
|
||||||
|
return newConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantValue* ConstantValue::get(float value) {
|
ConstantInteger* ConstantInteger::get(Type* type, int val) {
|
||||||
static std::map<float, std::unique_ptr<ConstantValue>> floatConstants;
|
return dynamic_cast<ConstantInteger*>(ConstantValue::get(type, val));
|
||||||
auto iter = floatConstants.find(value);
|
|
||||||
if (iter != floatConstants.end()) {
|
|
||||||
return iter->second.get();
|
|
||||||
}
|
|
||||||
auto inst = new ConstantValue(value);
|
|
||||||
assert(inst);
|
|
||||||
auto result = floatConstants.emplace(value, inst);
|
|
||||||
return result.first->second.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConstantFloating* ConstantFloating::get(Type* type, float val) {
|
||||||
|
return dynamic_cast<ConstantFloating*>(ConstantValue::get(type, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
UndefinedValue* UndefinedValue::get(Type* type) {
|
||||||
|
assert(!type->isVoid() && "Cannot get UndefinedValue of void type!");
|
||||||
|
|
||||||
|
auto it = UndefValues.find(type);
|
||||||
|
if (it != UndefValues.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
UndefinedValue* newUndef = new UndefinedValue(type);
|
||||||
|
UndefValues[type] = newUndef;
|
||||||
|
return newUndef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
auto Function::getCalleesWithNoExternalAndSelf() -> std::set<Function *> {
|
auto Function::getCalleesWithNoExternalAndSelf() -> std::set<Function *> {
|
||||||
std::set<Function *> result;
|
std::set<Function *> result;
|
||||||
for (auto callee : callees) {
|
for (auto callee : callees) {
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ class ValueCounter {
|
|||||||
|
|
||||||
// --- Refactored ConstantValue and related classes start here ---
|
// --- Refactored ConstantValue and related classes start here ---
|
||||||
|
|
||||||
using ConstantValVariant = std::variant<intmax_t, float>;
|
using ConstantValVariant = std::variant<int, float>;
|
||||||
|
|
||||||
// Helper for hashing std::variant
|
// Helper for hashing std::variant
|
||||||
struct VariantHash {
|
struct VariantHash {
|
||||||
@@ -320,6 +320,10 @@ struct ConstantValueEqual {
|
|||||||
* `Value`s. It's type is either `int` or `float`.
|
* `Value`s. It's type is either `int` or `float`.
|
||||||
* `ConstantValue`并不由指令定义, 也不使用任何Value。它的类型为int/float。
|
* `ConstantValue`并不由指令定义, 也不使用任何Value。它的类型为int/float。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
template<class T> struct always_false : std::false_type {};
|
||||||
|
template<class T> constexpr bool always_false_v = always_false<T>::value;
|
||||||
|
|
||||||
class ConstantValue : public Value {
|
class ConstantValue : public Value {
|
||||||
protected:
|
protected:
|
||||||
static std::unordered_map<ConstantValueKey, ConstantValue*, ConstantValueHash, ConstantValueEqual> mConstantPool;
|
static std::unordered_map<ConstantValueKey, ConstantValue*, ConstantValueHash, ConstantValueEqual> mConstantPool;
|
||||||
@@ -329,7 +333,7 @@ public:
|
|||||||
virtual ~ConstantValue() = default;
|
virtual ~ConstantValue() = default;
|
||||||
|
|
||||||
virtual size_t hash() const = 0;
|
virtual size_t hash() const = 0;
|
||||||
virtual ConstantValVariant getValue() const = 0;
|
virtual ConstantValVariant getVal() const = 0;
|
||||||
|
|
||||||
// Static factory method to get a canonical ConstantValue from the pool
|
// Static factory method to get a canonical ConstantValue from the pool
|
||||||
static ConstantValue* get(Type* type, ConstantValVariant val);
|
static ConstantValue* get(Type* type, ConstantValVariant val);
|
||||||
@@ -337,23 +341,23 @@ public:
|
|||||||
// Helper methods to access constant values with appropriate casting
|
// Helper methods to access constant values with appropriate casting
|
||||||
int getInt() const {
|
int getInt() const {
|
||||||
assert(getType()->isInt() && "Calling getInt() on non-integer type");
|
assert(getType()->isInt() && "Calling getInt() on non-integer type");
|
||||||
return std::get<int>(getValue());
|
return std::get<int>(getVal());
|
||||||
}
|
}
|
||||||
float getFloat() const {
|
float getFloat() const {
|
||||||
assert(getType()->isFloat() && "Calling getFloat() on non-float type");
|
assert(getType()->isFloat() && "Calling getFloat() on non-float type");
|
||||||
return std::get<float>(getValue());
|
return std::get<float>(getVal());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T getValue() const {
|
T getVal() const {
|
||||||
if constexpr (std::is_same_v<T, int>) {
|
if constexpr (std::is_same_v<T, int>) {
|
||||||
return getInt();
|
return getInt();
|
||||||
} else if constexpr (std::is_same_v<T, float>) {
|
} else if constexpr (std::is_same_v<T, float>) {
|
||||||
return getFloat();
|
return getFloat();
|
||||||
} else {
|
} else {
|
||||||
// This ensures a compilation error if an unsupported type is used
|
// This ensures a compilation error if an unsupported type is used
|
||||||
static_assert(std::always_false_v<T>, "Unsupported type for ConstantValue::getValue()");
|
static_assert(always_false_v<T>, "Unsupported type for ConstantValue::getValue()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isZero() const = 0;
|
virtual bool isZero() const = 0;
|
||||||
@@ -372,7 +376,7 @@ public:
|
|||||||
return typeHash ^ (valHash << 1);
|
return typeHash ^ (valHash << 1);
|
||||||
}
|
}
|
||||||
int getInt() const { return constVal; }
|
int getInt() const { return constVal; }
|
||||||
ConstantValVariant getValue() const override { return constVal; }
|
ConstantValVariant getVal() const override { return constVal; }
|
||||||
|
|
||||||
static ConstantInteger* get(Type* type, int val);
|
static ConstantInteger* get(Type* type, int val);
|
||||||
static ConstantInteger* get(int val) { return get(Type::getIntType(), val); }
|
static ConstantInteger* get(int val) { return get(Type::getIntType(), val); }
|
||||||
@@ -398,7 +402,7 @@ public:
|
|||||||
return typeHash ^ (valHash << 1);
|
return typeHash ^ (valHash << 1);
|
||||||
}
|
}
|
||||||
float getFloat() const { return constFVal; }
|
float getFloat() const { return constFVal; }
|
||||||
ConstantValVariant getValue() const override { return constFVal; }
|
ConstantValVariant getVal() const override { return constFVal; }
|
||||||
|
|
||||||
static ConstantFloating* get(Type* type, float val);
|
static ConstantFloating* get(Type* type, float val);
|
||||||
static ConstantFloating* get(float val) { return get(Type::getFloatType(), val); }
|
static ConstantFloating* get(float val) { return get(Type::getFloatType(), val); }
|
||||||
@@ -429,7 +433,7 @@ public:
|
|||||||
return std::hash<Type*>{}(getType());
|
return std::hash<Type*>{}(getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantValVariant getValue() const override {
|
ConstantValVariant getVal() const override {
|
||||||
if (getType()->isInt()) {
|
if (getType()->isInt()) {
|
||||||
return 0; // Return 0 for undefined integer
|
return 0; // Return 0 for undefined integer
|
||||||
} else if (getType()->isFloat()) {
|
} else if (getType()->isFloat()) {
|
||||||
@@ -443,52 +447,6 @@ public:
|
|||||||
bool isOne() const override { return false; }
|
bool isOne() const override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implementations for static members (typically in .cpp, but for single-file, put here)
|
|
||||||
|
|
||||||
std::unordered_map<ConstantValueKey, ConstantValue*, ConstantValueHash, ConstantValueEqual> ConstantValue::mConstantPool;
|
|
||||||
std::unordered_map<Type*, UndefinedValue*> UndefinedValue::UndefValues;
|
|
||||||
|
|
||||||
ConstantValue* ConstantValue::get(Type* type, ConstantValVariant val) {
|
|
||||||
ConstantValueKey key = {type, val};
|
|
||||||
auto it = mConstantPool.find(key);
|
|
||||||
if (it != mConstantPool.end()) {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantValue* newConstant = nullptr;
|
|
||||||
if (std::holds_alternative<int>(val)) {
|
|
||||||
newConstant = new ConstantInteger(type, std::get<int>(val));
|
|
||||||
} else if (std::holds_alternative<float>(val)) {
|
|
||||||
newConstant = new ConstantFloating(type, std::get<float>(val));
|
|
||||||
} else {
|
|
||||||
assert(false && "Unsupported ConstantValVariant type");
|
|
||||||
}
|
|
||||||
|
|
||||||
mConstantPool[key] = newConstant;
|
|
||||||
return newConstant;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantInteger* ConstantInteger::get(Type* type, int val) {
|
|
||||||
return dynamic_cast<ConstantInteger*>(ConstantValue::get(type, val));
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantFloating* ConstantFloating::get(Type* type, float val) {
|
|
||||||
return dynamic_cast<ConstantFloating*>(ConstantValue::get(type, val));
|
|
||||||
}
|
|
||||||
|
|
||||||
UndefinedValue* UndefinedValue::get(Type* type) {
|
|
||||||
assert(!type->isVoid() && "Cannot get UndefinedValue of void type!");
|
|
||||||
|
|
||||||
auto it = UndefValues.find(type);
|
|
||||||
if (it != UndefValues.end()) {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
UndefinedValue* newUndef = new UndefinedValue(type);
|
|
||||||
UndefValues[type] = newUndef;
|
|
||||||
return newUndef;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- End of refactored ConstantValue and related classes ---
|
// --- End of refactored ConstantValue and related classes ---
|
||||||
|
|
||||||
|
|
||||||
@@ -941,7 +899,7 @@ class PhiInst : public Instruction {
|
|||||||
PhiInst(Type *type,
|
PhiInst(Type *type,
|
||||||
const std::vector<Value *> &rhs = {},
|
const std::vector<Value *> &rhs = {},
|
||||||
const std::vector<BasicBlock*> &Blocks = {},
|
const std::vector<BasicBlock*> &Blocks = {},
|
||||||
BasicBlock *parent,
|
BasicBlock *parent = nullptr,
|
||||||
const std::string &name = "")
|
const std::string &name = "")
|
||||||
: Instruction(Kind::kPhi, type, parent, name), vsize(rhs.size()) {
|
: Instruction(Kind::kPhi, type, parent, name), vsize(rhs.size()) {
|
||||||
assert(rhs.size() == Blocks.size() && "PhiInst: rhs and Blocks must have the same size");
|
assert(rhs.size() == Blocks.size() && "PhiInst: rhs and Blocks must have the same size");
|
||||||
@@ -977,7 +935,6 @@ class PhiInst : public Instruction {
|
|||||||
void refreshB2VMap();
|
void refreshB2VMap();
|
||||||
|
|
||||||
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
|
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
|
||||||
Value* getValue(unsigned index) const { return getOperand(index + 1); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user