Skip to content

Commit 138403e

Browse files
ruslan-sckv-sc
authored andcommitted
[snippy] Support per-operand imm-hist
Adds the ability to separately specify values for each immediate operand separately in imm‑hist.
1 parent ff32fd2 commit 138403e

16 files changed

+425
-41
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
include:
2+
- sections.yaml
3+
4+
options:
5+
mtriple: riscv64-unknown-elf
6+
num-instrs: 100
7+
dump-mf: on
8+
mattr: +Zicsr,+f
9+
10+
histogram:
11+
- [CSRRWI, 1.0]
12+
13+
imm-hist:
14+
opcodes:
15+
- 'CSRRWI':
16+
operands:
17+
- - [0x2, 1.0] # First operand (CSR)
18+
- - [0x0, 1.0] # Second operand (Value to write)
19+
- [0x1, 1.0]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# RUN: llvm-snippy %s -model-plugin=None |& FileCheck %s
2+
3+
include:
4+
- Inputs/sections.yaml
5+
6+
options:
7+
mtriple: riscv64-unknown-elf
8+
num-instrs: 100
9+
dump-mf: on
10+
mattr: +Zicsr
11+
12+
histogram:
13+
- [CSRRWI, 1.0]
14+
15+
imm-hist:
16+
opcodes:
17+
- 'CSRRWI':
18+
operands:
19+
- - [0x2, 1.0] # First operand (CSR)
20+
- uniform # Second operand (Value to write)
21+
22+
# NOTE: We expect that the second imm-operand will be 5-bit immediate
23+
# CHECK-COUNT-100: CSRRWI 2, {{[0-9]|[1-2][0-9]|3[0-1]}}
24+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# RUN: llvm-snippy %S/Inputs/immediate-histogram-per-operand.yaml -model-plugin=None |& FileCheck %s
2+
3+
# CHECK-COUNT-100: CSRRWI 2, {{[0|1]}}

llvm/test/tools/llvm-snippy/immediate-histogram-regex-wrong-opcode-setting-error.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,4 @@ imm-hist:
1515
- "ADDI":
1616
nonexistent: mapping
1717

18-
# CHECK: error: Immediate histogram opcode setting should be either sequence or scalar.
19-
# CHECK-SAME: But map was encountered
20-
# CHECK: nonexistent: mapping
18+
# CHECK: error: missing required key 'operands'
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# RUN: not llvm-snippy %s -model-plugin=None |& FileCheck %s
2+
3+
include:
4+
- Inputs/sections.yaml
5+
6+
options:
7+
mtriple: riscv64-unknown-elf
8+
num-instrs: 100
9+
dump-mf: on
10+
mattr: +Zicsr
11+
12+
histogram:
13+
- [CSRRWI, 1.0]
14+
15+
imm-hist:
16+
opcodes:
17+
- 'CSRRWI':
18+
operands:
19+
- - [0x2, 1.0] # First operand (CSR)
20+
21+
# CHECK: error: Immediate histogram: The number of operands
22+
# CHECK-SAME: entries is not equal to the number of immediate
23+
# CHECK-SAME: operands for the "CSRRWI" opcode. Expected 2
24+
# CHECK-SAME: entries but 1 were specified
25+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# RUN: not llvm-snippy %s -model-plugin=None |& FileCheck %s
2+
3+
include:
4+
- Inputs/sections.yaml
5+
6+
options:
7+
mtriple: riscv64-unknown-elf
8+
num-instrs: 100
9+
dump-mf: on
10+
mattr: +Zicsr
11+
12+
histogram:
13+
- [CSRRWI, 1.0]
14+
15+
imm-hist:
16+
opcodes:
17+
- 'CSRRWI':
18+
operands:
19+
- - [0x2, 1.0] # First operand (CSR)
20+
- - [0x0, 1.0] # Second operand (Value to write)
21+
- [0x1, 1.0]
22+
- [0x2, 1.0]
23+
- - [0x0, 1.0] # Third operand (nonexistent)
24+
25+
# CHECK: error: Immediate histogram: The number of operands
26+
# CHECK-SAME: entries is not equal to the number of immediate
27+
# CHECK-SAME: operands for the "CSRRWI" opcode. Expected 2
28+
# CHECK-SAME: entries but 3 were specified
29+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# RUN: not llvm-snippy %s |& FileCheck %s
2+
3+
include:
4+
- Inputs/sections.yaml
5+
6+
options:
7+
mtriple: riscv64-unknown-elf
8+
num-instrs: 100
9+
dump-mf: on
10+
mattr: +Zicsr,+f
11+
12+
histogram:
13+
- [CSRRWI, 1.0]
14+
15+
imm-hist:
16+
opcodes:
17+
- 'CSRRWI':
18+
operands:
19+
- - [0x2, 1.0] # First operand (CSR)
20+
- nonexistent: mapping
21+
22+
# CHECK: error: Immediate histogram operands entry
23+
# CHECK-SAME: should be either sequence or scalar
24+
# CHECK: nonexistent: mapping

llvm/tools/llvm-snippy/include/snippy/Config/ImmediateHistogram.h

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,30 +44,99 @@ struct ImmediateHistogramSequence final {
4444
bool empty() const { return Values.empty(); }
4545
};
4646

47+
class ImmHistOperandsEntry final {
48+
public:
49+
enum class Kind { Uniform, Sequence };
50+
51+
ImmHistOperandsEntry() = default;
52+
53+
ImmHistOperandsEntry(const ImmediateHistogramSequence &Seq)
54+
: Underlying(Seq), EntryKind(Kind::Sequence) {}
55+
56+
bool isSequence() const { return EntryKind == Kind::Sequence; }
57+
58+
bool isUniform() const { return EntryKind == Kind::Uniform; }
59+
60+
Kind getKind() const { return EntryKind; }
61+
62+
const ImmediateHistogramSequence &getSequence() const & {
63+
assert(isSequence() &&
64+
std::holds_alternative<ImmediateHistogramSequence>(Underlying));
65+
return std::get<ImmediateHistogramSequence>(Underlying);
66+
}
67+
68+
private:
69+
std::variant<std::monostate, ImmediateHistogramSequence> Underlying;
70+
Kind EntryKind = Kind::Uniform;
71+
};
72+
73+
struct ImmHistOperandsEntryHolder final {
74+
ImmHistOperandsEntry Underlying;
75+
};
76+
77+
class ImmHistOperands final {
78+
std::vector<ImmHistOperandsEntryHolder> Operands;
79+
friend yaml::MappingTraits<ImmHistOperands>;
80+
81+
public:
82+
bool isUniformForOperand(unsigned OperandIdx) const {
83+
assert(Operands.size() > OperandIdx);
84+
return Operands[OperandIdx].Underlying.isUniform();
85+
}
86+
87+
bool hasIHForOperand(unsigned OperandIdx) const {
88+
assert(Operands.size() > OperandIdx);
89+
return Operands[OperandIdx].Underlying.isSequence();
90+
}
91+
92+
const ImmediateHistogramSequence &
93+
getIHForOperand(unsigned OperandIdx) const & {
94+
assert(Operands.size() > OperandIdx);
95+
assert(hasIHForOperand(OperandIdx));
96+
const auto &Entry = Operands[OperandIdx].Underlying;
97+
return Entry.getSequence();
98+
}
99+
100+
auto size() const { return Operands.size(); }
101+
};
102+
47103
class ImmHistOpcodeSettings final {
48104
public:
49-
enum class Kind { Uniform, Custom };
105+
enum class Kind { Uniform, Custom, Operands };
50106

51107
private:
52-
std::optional<ImmediateHistogramSequence> Seq;
108+
std::variant<std::monostate, ImmediateHistogramSequence, ImmHistOperands>
109+
Underlying;
53110
Kind SettingsKind = Kind::Uniform;
54111

55112
public:
56113
ImmHistOpcodeSettings() = default;
57114

58115
ImmHistOpcodeSettings(const ImmediateHistogramSequence &Sequence)
59-
: Seq(Sequence), SettingsKind(Kind::Custom) {}
116+
: Underlying(Sequence), SettingsKind(Kind::Custom) {}
60117

61118
ImmHistOpcodeSettings(ImmediateHistogramSequence &&Sequence)
62-
: Seq(std::move(Sequence)), SettingsKind(Kind::Custom) {}
119+
: Underlying(std::move(Sequence)), SettingsKind(Kind::Custom) {}
120+
121+
ImmHistOpcodeSettings(const ImmHistOperands &Map)
122+
: Underlying(Map), SettingsKind(Kind::Operands) {}
63123

64124
bool isUniform() const { return SettingsKind == Kind::Uniform; }
65125

66126
bool isSequence() const { return SettingsKind == Kind::Custom; }
67127

68-
const ImmediateHistogramSequence &getSequence() const {
69-
assert(isSequence() && Seq.has_value());
70-
return *Seq;
128+
bool isPerOperand() const { return SettingsKind == Kind::Operands; }
129+
130+
const ImmediateHistogramSequence &getSequence() const & {
131+
assert(isSequence() &&
132+
std::holds_alternative<ImmediateHistogramSequence>(Underlying));
133+
return std::get<ImmediateHistogramSequence>(Underlying);
134+
}
135+
136+
const ImmHistOperands &getOperandsMap() const & {
137+
assert(isPerOperand() &&
138+
std::holds_alternative<ImmHistOperands>(Underlying));
139+
return std::get<ImmHistOperands>(Underlying);
71140
}
72141

73142
Kind getKind() const { return SettingsKind; }
@@ -395,13 +464,25 @@ class OpcodeToImmHistSequenceMap final {
395464

396465
OpcodeToImmHistSequenceMap() = default;
397466

398-
const ImmHistOpcodeSettings &
399-
getConfigForOpcode(unsigned Opc, const OpcodeCache &OpCC) const {
467+
const ImmHistOpcodeSettings &getConfigForOpcode(unsigned Opc) const & {
400468
assert(Data.count(Opc) && "Opcode was not found in immediate histogram");
401469
return Data.at(Opc);
402470
}
471+
472+
bool empty() const { return Data.empty(); }
403473
};
404474

475+
struct ImmHistOperandsEntryMapMapper final {};
476+
405477
} // namespace snippy
478+
479+
namespace yaml {
480+
void yamlize(IO &IO, const snippy::ImmHistOperandsEntryMapMapper &, bool,
481+
EmptyContext &);
482+
} // namespace yaml
483+
484+
LLVM_SNIPPY_YAML_DECLARE_MAPPING_TRAITS(snippy::ImmHistOperands);
485+
LLVM_SNIPPY_YAML_DECLARE_MAPPING_TRAITS(snippy::ImmHistOperandsEntryHolder);
486+
LLVM_SNIPPY_YAML_IS_SEQUENCE_ELEMENT(snippy::ImmHistOperandsEntryHolder, false);
406487
LLVM_SNIPPY_YAML_DECLARE_MAPPING_TRAITS(snippy::ImmediateHistogramSequence);
407488
} // namespace llvm

llvm/tools/llvm-snippy/include/snippy/Target/Target.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,8 @@ class SnippyTarget {
355355
virtual MachineOperand
356356
generateTargetOperand(SnippyProgramContext &ProgCtx,
357357
const CommonPolicyConfig &Cfg, unsigned OpCode,
358-
unsigned OpType,
359-
const StridedImmediate &StridedImm) const = 0;
358+
unsigned OpType, const StridedImmediate &StridedImm,
359+
unsigned OperandIdx) const = 0;
360360

361361
virtual bool canProduceNaN(const MCInstrDesc &InstrDesc) const = 0;
362362

@@ -376,6 +376,8 @@ class SnippyTarget {
376376
return AccessMaskBit::None;
377377
}
378378

379+
virtual size_t getNumImmOperands(const MCInstrDesc &InstrDesc) const = 0;
380+
379381
virtual unsigned getTransformSequenceLength(InstructionGenerationContext &IGC,
380382
APInt OldValue, APInt NewValue,
381383
MCRegister Register) const = 0;

0 commit comments

Comments
 (0)