[PATCH] D60161: Expose non-trivial struct helpers for Swift.

2019-04-02 Thread Tony Allevato via Phabricator via cfe-commits
allevato created this revision.
allevato added a reviewer: rjmccall.
Herald added subscribers: cfe-commits, jdoerfert.
Herald added a project: clang.

This change exposes the helper functions that generate ctors/dtors
for non-trivial structs so that they can be called from the Swift
compiler (see https://github.com/apple/swift/pull/23405) to
enable it to import such C records.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D60161

Files:
  clang/include/clang/CodeGen/CodeGenABITypes.h
  clang/lib/CodeGen/CGNonTrivialStruct.cpp

Index: clang/lib/CodeGen/CGNonTrivialStruct.cpp
===
--- clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -14,6 +14,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/NonTrivialTypeVisitor.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include 
 
@@ -907,3 +908,71 @@
   callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile,
   *this, std::array({{DstPtr, SrcPtr}}));
 }
+
+void clang::CodeGen::callNonTrivialCStructDefaultConstructor(
+CodeGenModule &CGM, llvm::BasicBlock *BB,
+llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst,
+CharUnits DstAlignment, QualType QT) {
+  CodeGenFunction CGF(CGM, true);
+  CGF.Builder.SetInsertPoint(BB, InsertPoint);
+  LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment);
+  CGF.callCStructDefaultConstructor(DstLValue);
+}
+
+void clang::CodeGen::callNonTrivialCStructCopyConstructor(
+CodeGenModule &CGM, llvm::BasicBlock *BB,
+llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst,
+CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment,
+QualType QT) {
+  CodeGenFunction CGF(CGM, true);
+  CGF.Builder.SetInsertPoint(BB, InsertPoint);
+  LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment);
+  LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment);
+  CGF.callCStructCopyConstructor(DstLValue, SrcLValue);
+}
+
+void clang::CodeGen::callNonTrivialCStructMoveConstructor(
+CodeGenModule &CGM, llvm::BasicBlock *BB,
+llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst,
+CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment,
+QualType QT) {
+  CodeGenFunction CGF(CGM, true);
+  CGF.Builder.SetInsertPoint(BB, InsertPoint);
+  LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment);
+  LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment);
+  CGF.callCStructMoveConstructor(DstLValue, SrcLValue);
+}
+
+void clang::CodeGen::callNonTrivialCStructCopyAssignmentOperator(
+CodeGenModule &CGM, llvm::BasicBlock *BB,
+llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst,
+CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment,
+QualType QT) {
+  CodeGenFunction CGF(CGM, true);
+  CGF.Builder.SetInsertPoint(BB, InsertPoint);
+  LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment);
+  LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment);
+  CGF.callCStructCopyAssignmentOperator(DstLValue, SrcLValue);
+}
+
+void clang::CodeGen::callNonTrivialCStructMoveAssignmentOperator(
+CodeGenModule &CGM, llvm::BasicBlock *BB,
+llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst,
+CharUnits DstAlignment, llvm::Value *Src, CharUnits SrcAlignment,
+QualType QT) {
+  CodeGenFunction CGF(CGM, true);
+  CGF.Builder.SetInsertPoint(BB, InsertPoint);
+  LValue DstLValue = CGF.MakeAddrLValue(Dst, QT, DstAlignment);
+  LValue SrcLValue = CGF.MakeAddrLValue(Src, QT, SrcAlignment);
+  CGF.callCStructMoveAssignmentOperator(DstLValue, SrcLValue);
+}
+
+void clang::CodeGen::callNonTrivialCStructDestructor(
+CodeGenModule &CGM, llvm::BasicBlock *BB,
+llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst,
+CharUnits Alignment, QualType QT) {
+  CodeGenFunction CGF(CGM, true);
+  CGF.Builder.SetInsertPoint(BB, InsertPoint);
+  LValue lvalue = CGF.MakeAddrLValue(Dst, QT, Alignment);
+  CGF.callCStructDestructor(lvalue);
+}
Index: clang/include/clang/CodeGen/CodeGenABITypes.h
===
--- clang/include/clang/CodeGen/CodeGenABITypes.h
+++ clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -26,12 +26,14 @@
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/Type.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
+#include "llvm/IR/BasicBlock.h"
 
 namespace llvm {
   class DataLayout;
   class Module;
   class FunctionType;
   class Type;
+  class Value;
 }
 
 namespace clang {
@@ -83,6 +85,52 @@
 unsigned getLLVMFieldNumber(CodeGenModule &CGM,
 const RecordDecl *RD, const FieldDecl *FD);
 
+/// Generates a call to the default constructor for a C struct with
+/// non-trivially copyable fields.
+void callNonTrivialCStructDefaultConstructor(
+CodeGenModule &GCM, llvm::BasicBlock *BB,
+ll

[PATCH] D60161: Expose non-trivial struct helpers for Swift.

2019-04-03 Thread Tony Allevato via Phabricator via cfe-commits
allevato added inline comments.



Comment at: clang/include/clang/CodeGen/CodeGenABITypes.h:93
+llvm::BasicBlock::iterator InsertPoint, llvm::Value *Dst,
+CharUnits Alignment, QualType QT);
+

rjmccall wrote:
> Hmm.  I think it might be better to just have this return a function pointer; 
> emitting a call in a different frontend's function can be pretty fraught if 
> that frontend wants to handle e.g. unwinding.  The interface should document 
> the ABI of the returned function pointer.  Callers might be able to take 
> advantage of a function pointer in different ways, e.g. by using it directly 
> in Swift's value-witness tables on targets where the calling conventions 
> align.
> 
> In the long run, I'd definitely like to make this interface capable of doing 
> some limited code-generation tasks, e.g. to load or store bit-fields, but I 
> suspect that we'll need to think about that a bit more carefully and that we 
> might want to avoid anything that involves a call.
That makes sense—getting this working was a bit tricky and passing the BB and 
insert point didn't exactly seem like the cleanest approach.

I'll work on the alternate approach you suggested and circle back around when I 
have it working with the corresponding Swift changes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60161/new/

https://reviews.llvm.org/D60161



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60161: Expose non-trivial struct helpers for Swift.

2019-04-09 Thread Tony Allevato via Phabricator via cfe-commits
allevato updated this revision to Diff 194379.
allevato added a comment.

- Apply review changes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60161/new/

https://reviews.llvm.org/D60161

Files:
  clang/include/clang/CodeGen/CodeGenABITypes.h
  clang/lib/CodeGen/CGNonTrivialStruct.cpp

Index: clang/lib/CodeGen/CGNonTrivialStruct.cpp
===
--- clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -14,6 +14,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/NonTrivialTypeVisitor.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include 
 
@@ -822,6 +823,30 @@
   Gen.callFunc(FuncName, QT, Addrs, CGF);
 }
 
+template  std::array createNullAddressArray();
+
+template <> std::array createNullAddressArray() {
+  return std::array({Address(nullptr, CharUnits::Zero())});
+}
+
+template <> std::array createNullAddressArray() {
+  return std::array({Address(nullptr, CharUnits::Zero()),
+ Address(nullptr, CharUnits::Zero())});
+}
+
+template 
+static llvm::Function *
+generateSpecialFunction(G &&Gen, StringRef FuncName, QualType QT,
+bool IsVolatile, std::array Alignments,
+CodeGenModule &CGM) {
+  QT = IsVolatile ? QT.withVolatile() : QT;
+  // The following call requires an array of addresses as arguments, but doesn't
+  // actually use them (it overwrites them with the addresses of the arguments
+  // of the created function).
+  return Gen.getFunction(FuncName, QT, createNullAddressArray(), Alignments,
+ CGM);
+}
+
 // Functions to emit calls to the special functions of a non-trivial C struct.
 void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
   bool IsVolatile = Dst.isVolatile();
@@ -907,3 +932,70 @@
   callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile,
   *this, std::array({{DstPtr, SrcPtr}}));
 }
+
+llvm::Function *clang::CodeGen::generateNonTrivialCStructDefaultConstructor(
+CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return generateSpecialFunction(
+  GenDefaultInitialize(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::generateNonTrivialCStructCopyConstructor(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__copy_constructor_", DstAlignment,
+   SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return generateSpecialFunction(
+  GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::generateNonTrivialCStructMoveConstructor(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__move_constructor_", DstAlignment,
+  SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return generateSpecialFunction(
+  GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::generateNonTrivialCStructCopyAssignmentOperator(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__copy_assignment_", DstAlignment,
+   SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return generateSpecialFunction(
+  GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::generateNonTrivialCStructMoveAssignmentOperator(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__move_assignment_", DstAlignment,
+  SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return generateSpecialFunction(
+  GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::generateNonTrivialCStructDestructor(
+CodeGenModule &CGM, CharUnits Alignment, bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getCon

[PATCH] D60161: Expose non-trivial struct helpers for Swift.

2019-04-10 Thread Tony Allevato via Phabricator via cfe-commits
allevato updated this revision to Diff 194530.
allevato added a comment.

- Rename generate* to get* and cleanup param names.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60161/new/

https://reviews.llvm.org/D60161

Files:
  clang/include/clang/CodeGen/CodeGenABITypes.h
  clang/lib/CodeGen/CGNonTrivialStruct.cpp

Index: clang/lib/CodeGen/CGNonTrivialStruct.cpp
===
--- clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -14,6 +14,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/NonTrivialTypeVisitor.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include 
 
@@ -822,6 +823,29 @@
   Gen.callFunc(FuncName, QT, Addrs, CGF);
 }
 
+template  std::array createNullAddressArray();
+
+template <> std::array createNullAddressArray() {
+  return std::array({Address(nullptr, CharUnits::Zero())});
+}
+
+template <> std::array createNullAddressArray() {
+  return std::array({Address(nullptr, CharUnits::Zero()),
+ Address(nullptr, CharUnits::Zero())});
+}
+
+template 
+static llvm::Function *
+getSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile,
+   std::array Alignments, CodeGenModule &CGM) {
+  QT = IsVolatile ? QT.withVolatile() : QT;
+  // The following call requires an array of addresses as arguments, but doesn't
+  // actually use them (it overwrites them with the addresses of the arguments
+  // of the created function).
+  return Gen.getFunction(FuncName, QT, createNullAddressArray(), Alignments,
+ CGM);
+}
+
 // Functions to emit calls to the special functions of a non-trivial C struct.
 void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
   bool IsVolatile = Dst.isVolatile();
@@ -907,3 +931,69 @@
   callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile,
   *this, std::array({{DstPtr, SrcPtr}}));
 }
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructDefaultConstructor(
+CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return getSpecialFunction(GenDefaultInitialize(Ctx), FuncName, QT, IsVolatile,
+std::array({{DstAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructCopyConstructor(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__copy_constructor_", DstAlignment,
+   SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return getSpecialFunction(
+  GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructMoveConstructor(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__move_constructor_", DstAlignment,
+  SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return getSpecialFunction(
+  GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructCopyAssignmentOperator(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__copy_assignment_", DstAlignment,
+   SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return getSpecialFunction(
+  GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructMoveAssignmentOperator(
+CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenBinaryFuncName GenName("__move_assignment_", DstAlignment,
+  SrcAlignment, Ctx);
+  std::string FuncName = GenName.getName(QT, IsVolatile);
+  return getSpecialFunction(
+  GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
+  std::array({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructDestructor(
+CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
+  ASTContext &Ctx = CGM.getContext();
+  GenDestructorFuncName GenName("__

[PATCH] D60161: Expose non-trivial struct helpers for Swift.

2019-04-10 Thread Tony Allevato via Phabricator via cfe-commits
allevato marked 2 inline comments as done.
allevato added a comment.

Thanks for the review! This is ready to go on my end if there aren't any other 
comments.




Comment at: clang/lib/CodeGen/CGNonTrivialStruct.cpp:845
+  // actually use them (it overwrites them with the addresses of the arguments
+  // of the created function).
+  return Gen.getFunction(FuncName, QT, createNullAddressArray(), Alignments,

ahatanak wrote:
> I think `getFunction` shouldn't require passing addresses, but that's not 
> this patch's fault. I'll see if I can remove the parameter. 
Yeah, this hack bummed me out and I tried cleaning up the other related 
functions to have them not reuse the array in this way, but the way std::array 
and the template arg size_t N are currently being used throughout made those 
attempts ripple through in ways that would have required a deeper refactor.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60161/new/

https://reviews.llvm.org/D60161



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60161: Expose non-trivial struct helpers for Swift.

2019-04-10 Thread Tony Allevato via Phabricator via cfe-commits
allevato added a comment.

Oh, and in case I need to mention this (I don't contribute to llvm/clang 
frequently), I don't have commit access so I'll need someone else to merge it 
in. Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60161/new/

https://reviews.llvm.org/D60161



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits