[llvm-dev] Generating function definition for function that's only called during unwinding

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Generating function definition for function that's only called during unwinding

Dean Michael Berris via llvm-dev
Hi,

I'm trying to understand how clang keeps track of which declarations are called within a translation unit and decides to codegen their definitions.

DeclBase.h has a markUsed to keep track of ODR use, and I think that the decl can be found from the symbol table via ASTContext.h (for example looking up a template via GetQualifiedTemplateName -> getAsTemplateDecl -> setIsUsed ). This is just a result of fumbling around in the dark, I could be totally wrong.

I'd like to know what part of the system is responsible for tracking usage, and whether that's the same mechanism that decides whether to CodeGen basic blocks with function definitions.

Particularly, I'm curious about how the decision should be made whether to emit a definition for a destructor that it is only called in a cleanup block that's only invoked during unwinding. I don't actually understand how or whether the control flow for unwinding is expressed in the AST at all. I can't see anything related to unwinding control flow with -ast-dump for instance.

I've been spending some time debugging a particular test program at bug 33778 that fails to link because a block only referenced from an LSDA contains a call instruction to a destructor that has no generated definition. I'm hitting a wall because I'm pretty ignorant of the structure of the codebase and any guidance would be appreciated.

Any general guidance or documentation to help find my way around clang would be awesome too.

Thanks,
Keith

P.S. The program that doesn't link without -fno-exceptions:

#include <functional>

struct X {
   std::function<int()> F;
   std::function<int()> G;
};

void foo(const std::function<int()>& a) {
   new X{a, a};
}

int main() {
  return 0;
}

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Generating function definition for function that's only called during unwinding

Dean Michael Berris via llvm-dev
Hmmm... It seems like I should check out how the UseList on Value (and its child BasicBlock) work.

On Tue, May 1, 2018 at 8:34 PM, Keith Wyss <[hidden email]> wrote:
Hi,

I'm trying to understand how clang keeps track of which declarations are called within a translation unit and decides to codegen their definitions.

DeclBase.h has a markUsed to keep track of ODR use, and I think that the decl can be found from the symbol table via ASTContext.h (for example looking up a template via GetQualifiedTemplateName -> getAsTemplateDecl -> setIsUsed ). This is just a result of fumbling around in the dark, I could be totally wrong.

I'd like to know what part of the system is responsible for tracking usage, and whether that's the same mechanism that decides whether to CodeGen basic blocks with function definitions.

Particularly, I'm curious about how the decision should be made whether to emit a definition for a destructor that it is only called in a cleanup block that's only invoked during unwinding. I don't actually understand how or whether the control flow for unwinding is expressed in the AST at all. I can't see anything related to unwinding control flow with -ast-dump for instance.

I've been spending some time debugging a particular test program at bug 33778 that fails to link because a block only referenced from an LSDA contains a call instruction to a destructor that has no generated definition. I'm hitting a wall because I'm pretty ignorant of the structure of the codebase and any guidance would be appreciated.

Any general guidance or documentation to help find my way around clang would be awesome too.

Thanks,
Keith

P.S. The program that doesn't link without -fno-exceptions:

#include <functional>

struct X {
   std::function<int()> F;
   std::function<int()> G;
};

void foo(const std::function<int()>& a) {
   new X{a, a};
}

int main() {
  return 0;
}


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Generating function definition for function that's only called during unwinding

Dean Michael Berris via llvm-dev
I could be wrong here, but AFAICT, the implementation is allowed to elide initialisation/allocation if it can prove that the allocation is not observable. In this case, I would look at the generated IR and whether the call to ‘new’ turns into a ‘malloc’ that gets elided later. -O0 and/or other optimisation levels might do different things too.

If you change this to return the pointer and print it, do you get the destructor code-gen’ed?
On Wed, 2 May 2018 at 4:40 pm, Keith Wyss via llvm-dev <[hidden email]> wrote:
Hmmm... It seems like I should check out how the UseList on Value (and its child BasicBlock) work.

On Tue, May 1, 2018 at 8:34 PM, Keith Wyss <[hidden email]> wrote:
Hi,

I'm trying to understand how clang keeps track of which declarations are called within a translation unit and decides to codegen their definitions.

DeclBase.h has a markUsed to keep track of ODR use, and I think that the decl can be found from the symbol table via ASTContext.h (for example looking up a template via GetQualifiedTemplateName -> getAsTemplateDecl -> setIsUsed ). This is just a result of fumbling around in the dark, I could be totally wrong.

I'd like to know what part of the system is responsible for tracking usage, and whether that's the same mechanism that decides whether to CodeGen basic blocks with function definitions.

Particularly, I'm curious about how the decision should be made whether to emit a definition for a destructor that it is only called in a cleanup block that's only invoked during unwinding. I don't actually understand how or whether the control flow for unwinding is expressed in the AST at all. I can't see anything related to unwinding control flow with -ast-dump for instance.

I've been spending some time debugging a particular test program at bug 33778 that fails to link because a block only referenced from an LSDA contains a call instruction to a destructor that has no generated definition. I'm hitting a wall because I'm pretty ignorant of the structure of the codebase and any guidance would be appreciated.

Any general guidance or documentation to help find my way around clang would be awesome too.

Thanks,
Keith

P.S. The program that doesn't link without -fno-exceptions:

#include <functional>

struct X {
   std::function<int()> F;
   std::function<int()> G;
};

void foo(const std::function<int()>& a) {
   new X{a, a};
}

int main() {
  return 0;
}

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
--
-- Dean

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Generating function definition for function that's only called during unwinding

Dean Michael Berris via llvm-dev
In reply to this post by Dean Michael Berris via llvm-dev
You're probably barking up the wrong tree; the problem has nothing to do with code generation.  Consider the following testcase:

template<typename T> struct Z {
  T t;
  Z(const Z&) { throw 1; }
  ~Z() { *t = 10; }
};
struct X {
   Z<int> x;
   Z<int> y;
};
void foo(Z<int>& a) {
   new X{a, a};
}

This should emit an error because "t" can't be dereferenced.  gcc correctly the error; clang doesn't.

Not exactly sure why the destructor doesn't get marked odr-used, but I'd start with Sema::BuildCXXNew.

-Eli

On 5/1/2018 11:40 PM, Keith Wyss via llvm-dev wrote:
Hmmm... It seems like I should check out how the UseList on Value (and its child BasicBlock) work.

On Tue, May 1, 2018 at 8:34 PM, Keith Wyss <[hidden email]> wrote:
Hi,

I'm trying to understand how clang keeps track of which declarations are called within a translation unit and decides to codegen their definitions.

DeclBase.h has a markUsed to keep track of ODR use, and I think that the decl can be found from the symbol table via ASTContext.h (for example looking up a template via GetQualifiedTemplateName -> getAsTemplateDecl -> setIsUsed ). This is just a result of fumbling around in the dark, I could be totally wrong.

I'd like to know what part of the system is responsible for tracking usage, and whether that's the same mechanism that decides whether to CodeGen basic blocks with function definitions.

Particularly, I'm curious about how the decision should be made whether to emit a definition for a destructor that it is only called in a cleanup block that's only invoked during unwinding. I don't actually understand how or whether the control flow for unwinding is expressed in the AST at all. I can't see anything related to unwinding control flow with -ast-dump for instance.

I've been spending some time debugging a particular test program at bug 33778 that fails to link because a block only referenced from an LSDA contains a call instruction to a destructor that has no generated definition. I'm hitting a wall because I'm pretty ignorant of the structure of the codebase and any guidance would be appreciated.

Any general guidance or documentation to help find my way around clang would be awesome too.

Thanks,
Keith

P.S. The program that doesn't link without -fno-exceptions:

#include <functional>

struct X {
   std::function<int()> F;
   std::function<int()> G;
};

void foo(const std::function<int()>& a) {
   new X{a, a};
}

int main() {
  return 0;
}



_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev