Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLVM should support symbol aliasing #1389

Closed
asl opened this issue Nov 28, 2006 · 22 comments
Closed

LLVM should support symbol aliasing #1389

asl opened this issue Nov 28, 2006 · 22 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla llvm:core

Comments

@asl
Copy link
Collaborator

asl commented Nov 28, 2006

Bugzilla Link 1017
Resolution FIXED
Resolved on Sep 27, 2019 17:58
Version trunk
OS Linux
Blocks #1215 #1378
CC @lattner,@yuanfang-chen

Extended Description

LLVM should support symbol aliasing (the one, produced via
attribute((alias)) in gcc).

It seems, this is the main reason of #1378 , 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.

@asl
Copy link
Collaborator Author

asl commented Nov 28, 2006

assigned to @asl

@asl
Copy link
Collaborator Author

asl commented Nov 28, 2006

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?

@lattner
Copy link
Collaborator

lattner commented Nov 28, 2006

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.

@asl
Copy link
Collaborator Author

asl commented Nov 29, 2006

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));

  1. 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

@asl
Copy link
Collaborator Author

asl commented Apr 22, 2007

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"
  1. Alias target.
    The target symbols of an alias. E.g. "bar" in this examples

  2. 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.

@asl
Copy link
Collaborator Author

asl commented Apr 22, 2007

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.

@asl
Copy link
Collaborator Author

asl commented Apr 23, 2007

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.

@asl
Copy link
Collaborator Author

asl commented Apr 23, 2007

Patch also lacks some comments describing methods. They will be added.

@lattner
Copy link
Collaborator

lattner commented Apr 23, 2007

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

@asl
Copy link
Collaborator Author

asl commented Apr 23, 2007

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.).

@asl
Copy link
Collaborator Author

asl commented Apr 23, 2007

However, I agree, that code should be reviewed about creation of GV "copies".

@lattner
Copy link
Collaborator

lattner commented Apr 23, 2007

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

@llvmbot
Copy link
Collaborator

llvmbot commented Apr 23, 2007

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.

@lattner
Copy link
Collaborator

lattner commented Apr 23, 2007

  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.

  1. 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

@asl
Copy link
Collaborator Author

asl commented Apr 24, 2007

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.

@asl
Copy link
Collaborator Author

asl commented Apr 24, 2007

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.

@lattner
Copy link
Collaborator

lattner commented Apr 24, 2007

Looks great. Just to check, this is legal too right:

call i32 @​bar_f()

-Chris

@asl
Copy link
Collaborator Author

asl commented Apr 24, 2007

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?

@lattner
Copy link
Collaborator

lattner commented Apr 24, 2007

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

@asl
Copy link
Collaborator Author

asl commented Apr 24, 2007

Yes, definitely. Fixed.

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 27, 2021

mentioned in issue #1215

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 3, 2021
clementval pushed a commit to clementval/llvm-project that referenced this issue Jan 17, 2022
Update file ISO_Fortran_binding.h with "CFI" types for Fortran REAL and
COMPLEX kinds 2, 3, 10, 16, and modify KIND=16 IO to use descriptors.
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla llvm:core
Projects
None yet
Development

No branches or pull requests

3 participants