mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 11:10:05 +00:00
Replace opt::Instruction type and result cache with flags. (#1718)
Currentlty opt::Instruction class holds a cache of the result_id and type_id for the instruction. That cache needs to be updated if the underlying operand values are changes. This CL changes the cache to being a flag if there is a type or result id for the instruction. We then retrieve the value if needed from the operands.
This commit is contained in:
parent
3c19651733
commit
effafedcee
@ -36,24 +36,24 @@ Instruction::Instruction(IRContext* c)
|
||||
: utils::IntrusiveNodeBase<Instruction>(),
|
||||
context_(c),
|
||||
opcode_(SpvOpNop),
|
||||
type_id_(0),
|
||||
result_id_(0),
|
||||
has_type_id_(false),
|
||||
has_result_id_(false),
|
||||
unique_id_(c->TakeNextUniqueId()) {}
|
||||
|
||||
Instruction::Instruction(IRContext* c, SpvOp op)
|
||||
: utils::IntrusiveNodeBase<Instruction>(),
|
||||
context_(c),
|
||||
opcode_(op),
|
||||
type_id_(0),
|
||||
result_id_(0),
|
||||
has_type_id_(false),
|
||||
has_result_id_(false),
|
||||
unique_id_(c->TakeNextUniqueId()) {}
|
||||
|
||||
Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst,
|
||||
std::vector<Instruction>&& dbg_line)
|
||||
: context_(c),
|
||||
opcode_(static_cast<SpvOp>(inst.opcode)),
|
||||
type_id_(inst.type_id),
|
||||
result_id_(inst.result_id),
|
||||
has_type_id_(inst.type_id != 0),
|
||||
has_result_id_(inst.result_id != 0),
|
||||
unique_id_(c->TakeNextUniqueId()),
|
||||
dbg_line_insts_(std::move(dbg_line)) {
|
||||
assert((!IsDebugLineInst(opcode_) || dbg_line.empty()) &&
|
||||
@ -72,17 +72,17 @@ Instruction::Instruction(IRContext* c, SpvOp op, uint32_t ty_id,
|
||||
: utils::IntrusiveNodeBase<Instruction>(),
|
||||
context_(c),
|
||||
opcode_(op),
|
||||
type_id_(ty_id),
|
||||
result_id_(res_id),
|
||||
has_type_id_(ty_id != 0),
|
||||
has_result_id_(res_id != 0),
|
||||
unique_id_(c->TakeNextUniqueId()),
|
||||
operands_() {
|
||||
if (type_id_ != 0) {
|
||||
if (has_type_id_) {
|
||||
operands_.emplace_back(spv_operand_type_t::SPV_OPERAND_TYPE_TYPE_ID,
|
||||
std::initializer_list<uint32_t>{type_id_});
|
||||
std::initializer_list<uint32_t>{ty_id});
|
||||
}
|
||||
if (result_id_ != 0) {
|
||||
if (has_result_id_) {
|
||||
operands_.emplace_back(spv_operand_type_t::SPV_OPERAND_TYPE_RESULT_ID,
|
||||
std::initializer_list<uint32_t>{result_id_});
|
||||
std::initializer_list<uint32_t>{res_id});
|
||||
}
|
||||
operands_.insert(operands_.end(), in_operands.begin(), in_operands.end());
|
||||
}
|
||||
@ -90,16 +90,16 @@ Instruction::Instruction(IRContext* c, SpvOp op, uint32_t ty_id,
|
||||
Instruction::Instruction(Instruction&& that)
|
||||
: utils::IntrusiveNodeBase<Instruction>(),
|
||||
opcode_(that.opcode_),
|
||||
type_id_(that.type_id_),
|
||||
result_id_(that.result_id_),
|
||||
has_type_id_(that.has_type_id_),
|
||||
has_result_id_(that.has_result_id_),
|
||||
unique_id_(that.unique_id_),
|
||||
operands_(std::move(that.operands_)),
|
||||
dbg_line_insts_(std::move(that.dbg_line_insts_)) {}
|
||||
|
||||
Instruction& Instruction::operator=(Instruction&& that) {
|
||||
opcode_ = that.opcode_;
|
||||
type_id_ = that.type_id_;
|
||||
result_id_ = that.result_id_;
|
||||
has_type_id_ = that.has_type_id_;
|
||||
has_result_id_ = that.has_result_id_;
|
||||
unique_id_ = that.unique_id_;
|
||||
operands_ = std::move(that.operands_);
|
||||
dbg_line_insts_ = std::move(that.dbg_line_insts_);
|
||||
@ -109,8 +109,8 @@ Instruction& Instruction::operator=(Instruction&& that) {
|
||||
Instruction* Instruction::Clone(IRContext* c) const {
|
||||
Instruction* clone = new Instruction(c);
|
||||
clone->opcode_ = opcode_;
|
||||
clone->type_id_ = type_id_;
|
||||
clone->result_id_ = result_id_;
|
||||
clone->has_type_id_ = has_type_id_;
|
||||
clone->has_result_id_ = has_result_id_;
|
||||
clone->unique_id_ = c->TakeNextUniqueId();
|
||||
clone->operands_ = operands_;
|
||||
clone->dbg_line_insts_ = dbg_line_insts_;
|
||||
|
@ -107,8 +107,8 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
: utils::IntrusiveNodeBase<Instruction>(),
|
||||
context_(nullptr),
|
||||
opcode_(SpvOpNop),
|
||||
type_id_(0),
|
||||
result_id_(0),
|
||||
has_type_id_(false),
|
||||
has_result_id_(false),
|
||||
unique_id_(0) {}
|
||||
|
||||
// Creates a default OpNop instruction.
|
||||
@ -153,8 +153,12 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
// TODO(qining): Remove this function when instruction building and insertion
|
||||
// is well implemented.
|
||||
void SetOpcode(SpvOp op) { opcode_ = op; }
|
||||
uint32_t type_id() const { return type_id_; }
|
||||
uint32_t result_id() const { return result_id_; }
|
||||
uint32_t type_id() const {
|
||||
return has_type_id_ ? GetSingleWordOperand(0) : 0;
|
||||
}
|
||||
uint32_t result_id() const {
|
||||
return has_result_id_ ? GetSingleWordOperand(has_type_id_ ? 1 : 0) : 0;
|
||||
}
|
||||
uint32_t unique_id() const {
|
||||
assert(unique_id_ != 0);
|
||||
return unique_id_;
|
||||
@ -211,7 +215,7 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
inline void SetResultType(uint32_t ty_id);
|
||||
// Sets the result id
|
||||
inline void SetResultId(uint32_t res_id);
|
||||
inline bool HasResultId() const { return result_id_ != 0; }
|
||||
inline bool HasResultId() const { return has_result_id_; }
|
||||
// Remove the |index|-th operand
|
||||
void RemoveOperand(uint32_t index) {
|
||||
operands_.erase(operands_.begin() + index);
|
||||
@ -424,7 +428,9 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
private:
|
||||
// Returns the total count of result type id and result id.
|
||||
uint32_t TypeResultIdCount() const {
|
||||
return (type_id_ != 0) + (result_id_ != 0);
|
||||
if (has_type_id_ && has_result_id_) return 2;
|
||||
if (has_type_id_ || has_result_id_) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns true if the instruction declares a variable that is read-only. The
|
||||
@ -439,8 +445,8 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
|
||||
IRContext* context_; // IR Context
|
||||
SpvOp opcode_; // Opcode
|
||||
uint32_t type_id_; // Result type id. A value of 0 means no result type id.
|
||||
uint32_t result_id_; // Result id. A value of 0 means no result id.
|
||||
bool has_type_id_; // True if the instruction has a type id
|
||||
bool has_result_id_; // True if the instruction has a result id
|
||||
uint32_t unique_id_; // Unique instruction id
|
||||
// All logical operands, including result type id and result id.
|
||||
OperandList operands_;
|
||||
@ -506,28 +512,43 @@ inline void Instruction::SetInOperands(OperandList&& new_operands) {
|
||||
}
|
||||
|
||||
inline void Instruction::SetResultId(uint32_t res_id) {
|
||||
result_id_ = res_id;
|
||||
auto ridx = (type_id_ != 0) ? 1 : 0;
|
||||
assert(operands_[ridx].type == SPV_OPERAND_TYPE_RESULT_ID);
|
||||
// TODO(dsinclair): Allow setting a result id if there wasn't one
|
||||
// previously. Need to make room in the operands_ array to place the result,
|
||||
// and update the has_result_id_ flag.
|
||||
assert(has_result_id_);
|
||||
|
||||
// TODO(dsinclair): Allow removing the result id. This needs to make sure,
|
||||
// if there was a result id previously to remove it from the operands_ array
|
||||
// and reset the has_result_id_ flag.
|
||||
assert(res_id != 0);
|
||||
|
||||
auto ridx = has_type_id_ ? 1 : 0;
|
||||
operands_[ridx].words = {res_id};
|
||||
}
|
||||
|
||||
inline void Instruction::SetResultType(uint32_t ty_id) {
|
||||
if (type_id_ != 0) {
|
||||
type_id_ = ty_id;
|
||||
assert(operands_.front().type == SPV_OPERAND_TYPE_TYPE_ID);
|
||||
// TODO(dsinclair): Allow setting a type id if there wasn't one
|
||||
// previously. Need to make room in the operands_ array to place the result,
|
||||
// and update the has_type_id_ flag.
|
||||
assert(has_type_id_);
|
||||
|
||||
// TODO(dsinclair): Allow removing the type id. This needs to make sure,
|
||||
// if there was a type id previously to remove it from the operands_ array
|
||||
// and reset the has_type_id_ flag.
|
||||
assert(ty_id != 0);
|
||||
|
||||
operands_.front().words = {ty_id};
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Instruction::IsNop() const {
|
||||
return opcode_ == SpvOpNop && type_id_ == 0 && result_id_ == 0 &&
|
||||
return opcode_ == SpvOpNop && !has_type_id_ && !has_result_id_ &&
|
||||
operands_.empty();
|
||||
}
|
||||
|
||||
inline void Instruction::ToNop() {
|
||||
opcode_ = SpvOpNop;
|
||||
type_id_ = result_id_ = 0;
|
||||
has_type_id_ = false;
|
||||
has_result_id_ = false;
|
||||
operands_.clear();
|
||||
}
|
||||
|
||||
@ -576,9 +597,6 @@ inline void Instruction::ForEachInst(
|
||||
inline void Instruction::ForEachId(const std::function<void(uint32_t*)>& f) {
|
||||
for (auto& opnd : operands_)
|
||||
if (spvIsIdType(opnd.type)) f(&opnd.words[0]);
|
||||
if (type_id_ != 0u) type_id_ = GetSingleWordOperand(0u);
|
||||
if (result_id_ != 0u)
|
||||
result_id_ = GetSingleWordOperand(type_id_ == 0u ? 0u : 1u);
|
||||
}
|
||||
|
||||
inline void Instruction::ForEachId(
|
||||
|
Loading…
Reference in New Issue
Block a user