llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.02k stars 11.57k forks source link

Poor code when a pointer is a global var, but good code for static or local var #59043

Open markschimmel opened 1 year ago

markschimmel commented 1 year ago

If you add static before ptr below, or make it a local var in function main() it generates 3 store instruction storing constant integer data. If you leave it as-is it generates pretty poor code. Every element in each struct is written to and there is no padding in any struct so I don't see why it would behave differently for a global.

#include "stdlib.h"
#include "stdint.h"

typedef union reg1_t {
  uint32_t val;
  struct {
    uint32_t name1 :13;
    uint32_t name2 :6;
    uint32_t name3 :9;
    uint32_t name4 :4;
  } field;
} reg1_t; 

typedef union reg2_t {
  uint32_t val;
  struct {
    uint32_t name1 :7;
    uint32_t name2 :13;
    uint32_t name3 :12;
  } field;
} reg2_t; 

typedef union reg3_t {
  uint32_t val;
  struct{
    uint32_t name1 :13;
    uint32_t name2 :6;
    uint32_t name3 :9;
    uint32_t name4 :4;
  } field;
} reg3_t; 

typedef struct hw_reg {
  reg1_t reg1;
  reg2_t reg2;
  reg3_t reg3;
} hw_reg;

hw_reg *ptr = (hw_reg*) 0x90000000;

int main() {
  ptr->reg1.field.name1=3;
  ptr->reg1.field.name2=3;
  ptr->reg1.field.name3=3;
  ptr->reg1.field.name4=3;

  ptr->reg2.field.name1=3;
  ptr->reg2.field.name2=3;
  ptr->reg2.field.name3=3;

  ptr->reg3.field.name1=3;
  ptr->reg3.field.name2=3;
  ptr->reg3.field.name3=3;
  ptr->reg3.field.name4=3;
  return 0;
}
Leporacanthicus commented 1 year ago

I would have thought that is intentional - a global variable is unknown whether some other function, thread or such is reading/writing to it. (and if hwreg is actually a hardware register, it ought to be volatile and thus ALL modifications has to be written to to).

Obviously, making it static will allow the compiler to follow the uses of that variable, without worrying about some other functionality outside of the code it can currently see is also using this variable.

-- Mats


From: Mark Schimmel @.> Sent: 16 November 2022 22:38 To: llvm/llvm-project @.> Cc: Subscribed @.***> Subject: [llvm/llvm-project] Poor code when a pointer is a global var, but good code for static or local var (Issue #59043)

If you add "static" before "ptr" below, or make it a local var in function main() it generates 3 store instruction storing constant integer data. If you leave it as-is it generates pretty poor code. Every element in each struct is written to and there is no padding in any struct so I don't see why it would behave differently for a global.

include "stdlib.h"

include "stdint.h"

typedef union reg1_t { uint32_t val; struct { uint32_t name1 :13; uint32_t name2 :6; uint32_t name3 :9; uint32_t name4 :4; } field; } reg1_t;

typedef union reg2_t { uint32_t val; struct { uint32_t name1 :7; uint32_t name2 :13; uint32_t name3 :12; } field; } reg2_t;

typedef union reg3_t { uint32_t val; struct{ uint32_t name1 :13; uint32_t name2 :6; uint32_t name3 :9; uint32_t name4 :4; } field; } reg3_t;

typedef struct hw_reg { reg1_t reg1; reg2_t reg2; reg3_t reg3; } hw_reg;

hw_reg ptr = (hw_reg) 0x90000000;

int main() { ptr->reg1.field.name1=3; ptr->reg1.field.name2=3; ptr->reg1.field.name3=3; ptr->reg1.field.name4=3;

ptr->reg2.field.name1=3; ptr->reg2.field.name2=3; ptr->reg2.field.name3=3;

ptr->reg3.field.name1=3; ptr->reg3.field.name2=3; ptr->reg3.field.name3=3; ptr->reg3.field.name4=3; return 0; }

— Reply to this email directly, view it on GitHubhttps://github.com/llvm/llvm-project/issues/59043, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABUDZBIIPQPH6FV2BMVJ6O3WIVO7RANCNFSM6AAAAAASCXSXYA. You are receiving this because you are subscribed to this thread.Message ID: @.***>

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.