summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMaximilian Stemmer-Grabow <mail@mxsg.de>2021-09-13 17:48:34 +0200
committerAndreas Fried <andreas.fried@kit.edu>2021-12-02 12:57:28 +0100
commit34e224f548c52c4e05f425d3ead4878de585ea8f (patch)
treecbf0fc2f44eadc3d71112273b04e095d99bbede7
parent351e546d13441a703e820d81b2ec2cdc2a67c8af (diff)
Check for non-local immediate loads
-rw-r--r--ir/be/riscv/riscv_compression.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/ir/be/riscv/riscv_compression.c b/ir/be/riscv/riscv_compression.c
index 4704d7f..772f0b2 100644
--- a/ir/be/riscv/riscv_compression.c
+++ b/ir/be/riscv/riscv_compression.c
@@ -30,11 +30,8 @@ int riscv_get_op_compression_requirements(ir_node const *const node)
{
compression_req_t requirement = comp_req_unknown;
- // TODO Can this be done more elegantly?
- // Is there a globally valid map from opcodes to nodes (get_riscv_irn_opcode uses an offset to
- // correct the mapping
-
// Handle RISC-V-specific nodes
+
if(is_riscv_irn(node)) {
int opcode = get_riscv_irn_opcode(node);
@@ -42,8 +39,6 @@ int riscv_get_op_compression_requirements(ir_node const *const node)
switch(opcode) {
case iro_riscv_lw:
case iro_riscv_sw:
- // TODO This does not apply to stack-pointer-relative loads and stores
- // These should be handled separately
requirement = comp_req_register_subset;
break;
@@ -64,7 +59,6 @@ int riscv_get_op_compression_requirements(ir_node const *const node)
requirement = comp_req_always;
break;
- // TODO Branch instructions
// Branch instructions are compressible with the C.BEQZ and C.BNEZ compressed instructions
// These require:
@@ -72,9 +66,19 @@ int riscv_get_op_compression_requirements(ir_node const *const node)
// - An offset that fits into 8 bits (the LSB of the offset is omitted, behaves like offset[8:1]),
// it is sign-extended, this allows for a range of +/-256B
- // TODO Handle other immediate loads
case iro_riscv_lui: {
riscv_immediate_attr_t const *const imm = get_riscv_immediate_attr_const(node);
+
+ // Check whether the value loaded here is local in the current compilation unit.
+ // In this case, the value can be directly inserted before the executable is being linked,
+ // and the resulting load may be compressible. If not, the value will be inserted at link-time
+ // and the load instructions may never be compressed.
+ ir_entity* entity = imm->ent;
+ if (!entity_has_definition(entity)) {
+ requirement = comp_req_never;
+ break;
+ }
+
int32_t val = imm->val;
int32_t upper_val = val >> 12; // The lower 12 bits are ignored by lui
@@ -88,6 +92,13 @@ int riscv_get_op_compression_requirements(ir_node const *const node)
riscv_immediate_attr_t const *const imm = get_riscv_immediate_attr_const(node);
int32_t val = imm->val;
+ // See above for rationale
+ ir_entity* entity = imm->ent;
+ if (!entity_has_definition(entity)) {
+ requirement = comp_req_never;
+ break;
+ }
+
requirement = riscv_fits_into(val, 6) ? comp_req_2addr : comp_req_never;
break;
}
@@ -125,7 +136,6 @@ int riscv_get_op_compression_requirements(ir_node const *const node)
}
case iro_riscv_add:
- // TODO This should not be always, check the operands
requirement = comp_req_2addr;
break;
@@ -158,21 +168,6 @@ int riscv_get_op_compression_requirements(ir_node const *const node)
// TODO This should emit a register subset requirement, but among the two output values of this node
// requirement = comp_req_register_subset;
}
-
- // TODO This should be handled separately
- // Stack-pointer-relative adds are scaled differently from other offsets
- // else if(be_is_IncSP(node)) {}
- // Special instruction: C.ADDI16SP
-
- // else {
- // unsigned opcode = get_irn_opcode(node);
- //
- // switch (opcode) {
- // default:
- // requirement = comp_req_unknown;
- // break;
- // }
- // }
}
return (int)requirement;