Not to consolidate two structs with the same data types (but different names) in configure/make tool chain

Hi,

I have the following C code.

#define PTR_T char *

typedef struct objcache {
  PTR_T data;
  int cs; /* cache size, number of objects */
  int nc; /* number of cache entries */
} sh_obj_cache_t;

struct dstack {
  char *delimiters;
  int delimiter_depth;
  int delimiter_space;
};

When it is configured/made to generate IR with the following
environment variables,

CC=clang CXX=clang++ RANLIB=llvm-ranlib CFLAGS=-flto LDFLAGS=-flto\
-fuse-ld=gold\ -Wl\,-plugin-opt=save-temps

I see all the variables declared as sh_obj_cache_t in the source code
becomes of type %struct.dstack instead of %struct.objcache.

sh_obj_cache_t wdcache = {0, 0, 0};

@wdcache = dso_local global %struct.dstack zeroinitializer, align 8, !dbg !1189

If I directly compile the .c file to .ll, I will not see this problem.

Is there a way to still use the configure/make toolchain, yet still
maintain the original type information instead of consolidating types
of the same data? Thanks.

https://llvm.org/docs/LangRef.html#structure-types

Fundamentally, llvm is not designed to preserve details about front end language features.

LLVM Language Reference Manual — LLVM 18.0.0git documentation

I don't follow the above link. Could you help explain what it means?

Fundamentally, llvm is not designed to preserve details about front end language features.

If directly compile .c to .ll can preserve the original struct
information even they are essentially the same, why flto can not? It
seems to me that there must be a way to preserve such info if flto is
used.

LTO has to merge the modules from different translation units. Those modules very likely have duplicate types in them so LTO merges them to avoid wasting memory on duplicates.

LTO has to merge the modules from different translation units. Those modules very likely have duplicate types in them so LTO merges them to avoid wasting memory on duplicates.

But I am checking the *.preopt.bc. Since it is before any
optimization, I'd expect such merging should not occur.

It’s not an “optimization”. It’s done as part of module merging to create the preopt.bc file.