clangupc / clang-upc

Clang UPC Front-End
https://clangupc.github.io/
Other
16 stars 5 forks source link

OSX: fail to link UPC program #11

Closed nenadv closed 11 years ago

nenadv commented 11 years ago

After various fixes to the build environment I was able to install the compiler. However, the program does not link. There are two issues with this:

  1. "main" has to be renamed to become "_upc_main" (instead of "upc_main"). Here is the change I made:
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -321,7 +321,7 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
     }
     Builder.append("extern const int MYTHREAD;\n");
     Builder.append("typedef shared struct upc_lock_struct upc_lock_t;\n");
-    Builder.append("extern int main() __asm__(\"upc_main\");\n");
+    Builder.append(Twine("extern int main() __asm__(\"") + TI.getUserLabelPrefix() + "upc_main\");\n");
     Builder.defineMacro("exit", "__upc_exit");
  1. void darwin::Link::ConstructJob in Driver/Tools.cpp needs to add the UPC specific object files (upc_crtxxxx) and "-lupc" library on the link line.

I tried following the changes from the linuxtools procedure but that did not work:

After I compile a simple program I get the following for the link command:

/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld" -dynamic -arch x86_64 -macosx_version_min 10.8.0 -o t upc-crtbegin.o -lupc /var/folders/z7/83zx0wdj4cx644rg7p7kgwb80000gn/T/t-4uqNps.o -lSystem upc-crtend.o

After hard codding the link line into something like this:

/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld -dynamic -arch x86_64 -macosx_version_min 10.8.0 -o t /usr/local/clang-upc/lib/upc-crtbegin.o -L/usr/local/clang-upc/lib -lupc t.o -lSystem /usr/local/clang-upc/lib/upc-crtend.o

I am able to link and later execute the UPC program.

nenadv commented 11 years ago

One thing to note is that we are executing /usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld instead of /usr/bin/ld. But that seems to be a link to /usr/bin/ld.

I made an additional change:

--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -54,6 +54,8 @@ Darwin::Darwin(const Driver &D, const llvm::Triple& Triple)
   llvm::raw_string_ostream(MacosxVersionMin)
     << Major << '.' << Minor << '.' << Micro;

+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+
   // FIXME: DarwinVersion is only used to find GCC's libexec directory.
   // It should be removed when we stop supporting that.
   DarwinVersion[0] = Minor + 4;

With above change and additional changes to the Tools.cpp:

diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 9086505..07c8c0b 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -4074,6 +4074,9 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
                                 const InputInfoList &Inputs,
                                 const ArgList &Args,
                                 const char *LinkingOutput) const {
+  const toolchains::Darwin& ToolChain = getDarwinToolChain();
+  const Driver &D = ToolChain.getDriver();
+
   assert(Output.getType() == types::TY_Image && "Invalid linker output type.");

   // The logic here is derived from gcc's behavior; most of which
@@ -4189,6 +4192,16 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
           }
         }
       }
+      if (D.CCCIsUPC) {
+        const char *upc_crtbegin;
+        if (Args.hasArg(options::OPT_static))
+          upc_crtbegin = "upc-crtbeginT.o";
+        else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+          upc_crtbegin = "upc-crtbeginS.o";
+        else
+          upc_crtbegin = "upc-crtbegin.o";
+        CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(upc_crtbegin)));
+      }
     }

     if (!getDarwinToolChain().isTargetIPhoneOS() &&
@@ -4202,6 +4215,12 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,

   Args.AddAllArgs(CmdArgs, options::OPT_L);

+  const ToolChain::path_list Paths = ToolChain.getFilePaths();
+
+  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
+       i != e; ++i)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+
   // If we're building a dynamic lib with -faddress-sanitizer, unresolved
   // symbols may appear. Mark all of them as dynamic_lookup.
   // Linking executables is handled in lib/Driver/ToolChains.cpp.
@@ -4218,6 +4237,42 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
     // This is more complicated in gcc...
     CmdArgs.push_back("-lgomp");

+  if (D.CCCIsUPC && !Args.hasArg(options::OPT_nostdlib)) {
+    llvm::SmallString<32> Buf("-lupc");
+    if (Args.getLastArgValue(options::OPT_fupc_pts_EQ, "packed") == "struct") {
+      Buf += "-s";
+    }
+    if (Args.getLastArgValue(options::OPT_fupc_pts_vaddr_order_EQ, "first") == "last") {
+      Buf += "-l";
+    }
+    if (Arg * A = Args.getLastArg(options::OPT_fupc_packed_bits_EQ)) {
+      llvm::SmallVector<llvm::StringRef, 3> Bits;
+      StringRef(A->getValue(Args)).split(Bits, ",");
+      bool okay = true;
+      int Values[3];
+      if (Bits.size() == 3) {
+        for (int i = 0; i < 3; ++i)
+          if (Bits[i].getAsInteger(10, Values[i]) || Values[i] <= 0)
+            okay = false;
+        if (Values[0] + Values[1] + Values[2] != 64)
+          okay = false;
+      } else {
+        okay = false;
+      }
+      if (okay) {
+        if(Values[0] != 20 || Values[1] != 10 || Values[2] != 34) {
+          Buf += "-";
+          Buf += Bits[0];
+          Buf += "-";
+          Buf += Bits[1];
+          Buf += "-";
+          Buf += Bits[2];
+        }
+      }
+    }
+    CmdArgs.push_back(Args.MakeArgString(Buf));
+  }
+
   getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);

   if (isObjCRuntimeLinked(Args)) {
@@ -4265,7 +4320,17 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
   if (!Args.hasArg(options::OPT_A) &&
       !Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nostartfiles)) {
-    // endfile_spec is empty.
+
+    if (D.CCCIsUPC) {
+      const char *upc_crtend;
+      if (Args.hasArg(options::OPT_static))
+        upc_crtend = "upc-crtendT.o";
+      else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+        upc_crtend = "upc-crtendS.o";
+      else
+        upc_crtend = "upc-crtend.o";
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(upc_crtend)));
+    }
   }

   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);

I am am able to run the clang tests.

160 tests passed, 4 tests failed
Tests ended at: Thu Mar  7 14:45:37 PST 2013

The failing tests are related to:

/usr/local/clang-upc/bin/clangupc  -I. -O3  -Wall -Wextra -Wwrite-strings -Werror -fupc-threads-8 -g compound_test1.upc -o c
ompound_test1
fatal error: error in backend: Global variable '__upc_init_array' has an invalid section specifier 'upc_init_array': mach-o 
section specifier requires a segment and section separated by a comma.
[...]
test: barrier_neg opt: -O3 threads: static elapsed: 0.631 user: 0.003 sys: 0.024
./barrier_neg: UPC error: Two successive upc_notify statements executed without an intervening upc_wait
thread 5 terminated with signal: 'Abort trap'
/usr/local/bin/timeout: line 54: 16553 Terminated: 15          "$@"
nenadv commented 11 years ago

Note that above change to add "../lib" to the file paths was tailored on some other tool chains that have a comment like this: "tool chain which can call as(1) and ld(1) directly".

nenadv commented 11 years ago

With and additional change under #8 bug, I was able to pass the clang tests. Well, all except one in upc-semantics test suite that generated a different line number for the note:

-:152:28: note: expanded from macro 'UPC_MAX_BLOCK_SIZE' +:159:28: note: expanded from macro 'UPC_MAX_BLOCK_SIZE'

swatanabe commented 11 years ago

These changes look good. (Although the -lupc logic should probably be factored out into a separate function). Please commit this.

nenadv commented 11 years ago

Fixed in https://github.com/Intrepid/clang-upc/commit/c85d44e30c6fbc33fdb3b8482153a98b2c94f754