LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 1017 - LLVM should support symbol aliasing
Summary: LLVM should support symbol aliasing
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Core LLVM classes (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Anton Korobeynikov
URL:
Keywords:
Depends on:
Blocks: 843 1006
  Show dependency tree
 
Reported: 2006-11-28 01:55 PST by Anton Korobeynikov
Modified: 2019-09-27 17:58 PDT (History)
5 users (show)

See Also:
Fixed By Commit(s):


Attachments
Proposed solution (25.17 KB, patch)
2007-04-22 19:15 PDT, Anton Korobeynikov
Details
New solution (29.64 KB, patch)
2007-04-24 04:21 PDT, Anton Korobeynikov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Anton Korobeynikov 2006-11-28 01:55:37 PST
LLVM should support symbol aliasing (the one, produced via
__attribute((alias))__ in gcc).

It seems, this is the main reason of PR1006, since compatibility is achieved via
symbol aliasing.

Aliasing, seems, can be done in some painless way for functions: just clone it
or output the "stub", which will call original one.

Anyway, this is just cheap workaround. Aliasing should be introduced for GV's also.
Comment 1 Anton Korobeynikov 2006-11-28 02:00:42 PST
Sorry, I was wrong. alias is function attribute (in accordance to
http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/gcc/Function-Attributes.html).

So, maybe it will be better just to emit stub?
Comment 2 Chris Lattner 2006-11-28 14:50:06 PST
Can you include a link to spec that describes what aliases and weak aliases do, and how they are handled 
by the linker?  Maybe the gas/gnu ld manuals describe them.
Comment 3 Anton Korobeynikov 2006-11-28 16:14:05 PST
The codegen for aliases seems to be higly platform-dependend. However, I've
tested it on Linux & mingw32 targets and both resulted to the same code:

1. Input

void my_memcpy(void* outp, const void* inp, size_t length)
__attribute__((alias("memcpy"), weak));


2. Output

2.1 Mingw32 (note, there is no "weak" attribute here, since there are no weak
symbols here)

.globl _my_memcpy
.set   _my_memcpy,_memcpy

2.1 Linux
.weak _my_memcpy
.set  _my_memcpy,_memcpy

In terms of LLVM, my_memcpy gets external weak linkage, since there is no code
for it.

The documentation for .set is here:

http://sourceware.org/binutils/docs-2.17/as/Pseudo-Ops.html#Pseudo-Ops
Comment 4 Anton Korobeynikov 2007-04-22 13:33:56 PDT
Well. It was much discussion about symbol aliases in llvm-commits. Let's move here.

Terminology:

1. Alias
Alias is an external function/variable declaration with extra "alias target".
This addendum causes the declaration to be emitted as an alias for another
symbol. So, all uses of alias will be substituted by alias target by linker.

Examples:
 - gcc:  void foo() __attribute__ ((alias ("bar")));
 - LLVM (proposed): declare void @foo() alias "bar"

2. Alias target.
The target symbols of an alias. E.g. "bar" in this examples

3. Function/Variable part of an alias.
This is alias with target part removed. This part is just external
function/variable declaration.

Features:
Aliases acts as external function/variable declaration. So, they can have
linkage (external, external weak), function aliases can have CC.
Comment 5 Anton Korobeynikov 2007-04-22 13:41:48 PDT
My last proposal was:

1. Introduce new table in the Module for alias targets.
2. User normal Function's and GV's for aliases. They will be just
external function/variable *declarations*. Everything will be ok. 
3. Add methods setAliasTarget(), stripAlias() to GV class to add/remove
entries to alias target table. +some utility functions to deal with this
table during e.g. object destruction/copying/parent change.
4. Let Verifier reject such GV's and Functions, which has
initializer/body and entry in the alias target table.
5. AsmParser should reject usage of alias and initializer/body as well.
6. Let Linker "propagate" alias targets, if possible.
7. During codegen query alias target entry for each MO_ExternalSymbol to
check, whether there is any alias target. And emit needed code.
Comment 6 Anton Korobeynikov 2007-04-22 19:15:39 PDT
Created attachment 792 [details]
Proposed solution

This patch implements the proposed solution. Linker & Verifier part is still
missing, however. Both function aliases and variable aliases are supported.

Also it does some ugly code cleanup and formatting cleanup. Hope, this won't
make review harder.
Comment 7 Anton Korobeynikov 2007-04-22 19:16:31 PDT
Patch also lacks some comments describing methods. They will be added.
Comment 8 Chris Lattner 2007-04-22 19:29:27 PDT
Overall, this approach is better than extending function or globalvar with information.  However, the bad 
part of this approach is that it means that things which manipulate the global/function list of the module 
need to update the mapping.  As one example, the dead argument elim pass deletes Functions and then 
reallocates them (with fewer arguments).  With this design, each pass that does similar things would have 
to say "is there any aliases for this function?  If so, move it".

What is wrong with having a list of GlobalAlias objects in Module?

-Chris
Comment 9 Anton Korobeynikov 2007-04-22 19:38:22 PDT
DAE shouldn't touch aliases, because they are external declarations. I don't see
the difference between current approach and making new GlobalAliases class. The
second approach (GA) is worse, because function aliases and variable aliases
differs (For example, function aliases act like Function, so they have e.g. CC,
argument list, etc.).
Comment 10 Anton Korobeynikov 2007-04-22 19:40:58 PDT
However, I agree, that code should be reviewed about creation of GV "copies".
Comment 11 Chris Lattner 2007-04-22 19:48:29 PDT
> DAE shouldn't touch aliases, because they are external declarations. I don't see
> the difference between current approach and making new GlobalAliases class.

Actually, it makes a huge difference.  Consider the following:

static void foo(int X) alias 'bar' {  no uses of X }
void baz() { foo(1); }

In this case, DAE will delete the X argument to foo, even though foo is aliased to bar, and external 
callers could call it, and will pass the argument.  Thus, this is an illegal transformation.

I propose that you model the code like this:

@bar = alias void @foo(i32)
define internal void @foo(i32 %X) { ... }
define void @bar(...

In this design, bar is an instance of the GlobalAlias class.  The global alias class is required to have a 
name (enforced by the verifier) and has a single operand: the global that it is aliased to.  If you followed 
this approach, it would be trivial for the codegen to emit the alias info to the .s file, and the use by the 
alias would make DAE see that this function is exposed to the outside world (it would treat it as having 
its address taken, which is the right thing).

Also, because the alias uses the global as an operand, things like replacealluseswith would update the 
alias automatically etc.

What is the disadvantage of this approach?

-Chris 
Comment 12 Reid Spencer 2007-04-22 20:10:14 PDT
FWIW, the design Chris just proposed sounds right to me. Its close to what I was
trying to get across on the llvm-commits list: just make the Alias class
reference the thing it is renaming. Making a GlobalAlias class that derives from
GlobalValue sounds like the right thing to me.  

In some cases, however, it might still be possible to have DAE alter an aliased
function. A few things could be done:

1. If the Alias is internal, then DAE could update the calls to all the 
   aliases as well.
2. If the Alias is external, it could create a body for the aliased function
   (with the arguments being removed) that just calls the modified function.
Comment 13 Chris Lattner 2007-04-22 20:12:36 PDT
> 1. If the Alias is internal, then DAE could update the calls to all the 
>   aliases as well.

If the alias were internal, some other pass should have RAUW'd it with the target, then deleted it.

> 2. If the Alias is external, it could create a body for the aliased function
>  (with the arguments being removed) that just calls the modified function.

In practice, this probably isn't worth it.  Even if it were, DAE could do this today for any address-
exposed function if it wanted to, aliases aren't a special case here.

-Chris
Comment 14 Anton Korobeynikov 2007-04-24 04:21:49 PDT
Created attachment 795 [details]
New solution

This patch implements GlobalAlias class among with all changes in bytecode
reading/writing, codegen and asmprinting. Linker, Verifier and GlobalOpt's
aliases propagation left for the second step.

Example syntax:

@foo = external global i32
@bar = external alias i32* @foo

declare i32 @foo_f()
@bar_f = extern_weak alias i32()* @foo_f

define i32 @test() {
entry:
   %tmp = load i32* @foo
   %tmp2 = call i32 @foo_f()
   %tmp3 = add i32 %tmp, %tmp2
   ret i32 %tmp3
}

Unfortunately I had to force linkage for aliases use same syntax as GV's
external alias in order not to create additional parser conflicts.
Comment 15 Anton Korobeynikov 2007-04-24 10:58:15 PDT
The syntax will be changed to:

@foo = external global i32
@bar = alias i32* @foo

declare i32 @foo_f()
@bar_f = alias weak i32()* @foo_f

define i32 @test() {
entry:
   %tmp = load i32* @foo
   %tmp2 = call i32 @foo_f()
   %tmp3 = add i32 %tmp, %tmp2
   ret i32 %tmp3
}

I won't resubmit patch, since this change won't affect the review.
Comment 16 Chris Lattner 2007-04-24 11:06:47 PDT
Looks great.  Just to check, this is legal too right:

call i32 @bar_f()

-Chris
Comment 17 Anton Korobeynikov 2007-04-24 14:23:14 PDT
Hmm. This seems to be illegal, because aliases are "seen" as externals. So, in
order to make a call, extra load will be needed, e.g. something like this:

   %tmp_f = load %FunTy** @bar_f
   %tmp4 = call %FunTy* %tmp_f()

Should this behaviour be fixed with function aliases?
Comment 18 Chris Lattner 2007-04-24 14:51:55 PDT
I thought aliases are "another name for" the global.  If so, you should be able to refer to the global or the 
alias with equivalent effect, no?  In other words, the global and the alias should have the same type.

-Chris
Comment 19 Anton Korobeynikov 2007-04-24 15:02:52 PDT
Yes, definitely. Fixed.