Skip to content

Commit

Permalink
Fix inline functions on windows (#405)
Browse files Browse the repository at this point in the history
* Add inline function test

* Provide a partial fix for the inline problem, but not the stdio-specific problem.

* Disable tests again because test environment can't find legacy stdio lib

* Fix permissions.
  • Loading branch information
Erik McClure authored and elliottslaughter committed Oct 3, 2019
1 parent 11ad957 commit 39764e6
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 16 deletions.
18 changes: 17 additions & 1 deletion src/tcwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,22 +857,38 @@ static void optimizemodule(TerraTarget * TT, llvm::Module * M) {
//in some cases clang will mark stuff AvailableExternally (e.g. atoi on linux)
//the linker will then delete it because it is not used.
//switching it to WeakODR means that the linker will keep it even if it is not used
std::vector<llvm::Constant*> usedArray;

for(llvm::Module::iterator it = M->begin(), end = M->end();
it != end;
++it) {
llvm::Function * fn = &*it;
if(fn->hasAvailableExternallyLinkage()) {
fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
}
#ifdef _WIN32 // On windows, the optimizer will delete LinkOnce functions that are unused
usedArray.push_back(fn);
#endif
#if LLVM_VERSION >= 35
if(fn->hasDLLImportStorageClass()) //clear dll import linkage because it messes up the jit on window
fn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
#else
if(fn->hasDLLImportLinkage()) //clear dll import linkage because it messes up the jit on window
fn->setLinkage(llvm::GlobalValue::ExternalLinkage);

#endif
}

if(usedArray.size() > 0) {
auto* i8PtrType = llvm::Type::getInt8PtrTy(M->getContext());
for(auto& elem : usedArray)
elem = llvm::ConstantExpr::getBitCast(elem, i8PtrType);

auto* arrayType = llvm::ArrayType::get(i8PtrType, usedArray.size());
auto* llvmUsed = new llvm::GlobalVariable(*M, arrayType, false, llvm::GlobalValue::AppendingLinkage,
llvm::ConstantArray::get(arrayType, usedArray), "llvm.used");
llvmUsed->setSection("llvm.metadata");
}

M->setTargetTriple(TT->Triple); //suppress warning that occur due to unmatched os versions
PassManager opt;
llvmutil_addtargetspecificpasses(&opt, TT->tm);
Expand Down
3 changes: 2 additions & 1 deletion tests/benchmark_nbody.t
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
local C = terralib.includecstring[[
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
]]

C.printf = terralib.externfunction("printf", terralib.types.funcpointer(rawstring,int,true))

pi = 3.141592653589793
solar_mass = (4 * pi * pi)
days_per_year = 365.24
Expand Down
4 changes: 1 addition & 3 deletions tests/class2.t
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,4 @@ end
local test = require("test")
test.eq(foo(),9)

terralib.saveobj("class2", "executable", {
main = terra() S.printf("foo() = %d\n", foo()) end,
}, (jit.os == "Windows" and "\\legacy_stdio_definitions.lib" or nil))
terralib.saveobj("class2", "executable", {main = terra() S.printf("foo() = %d\n", foo()) end})
9 changes: 9 additions & 0 deletions tests/inline_c.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
C = terralib.includecstring[[inline int testfunc(int a, int b) { return a + b; }]]

terra foobar() : int
var a : int = 5
return C.testfunc(a, 9)
end
assert(foobar() == 14)

terralib.saveobj("inline_c.exe", {main = foobar})
10 changes: 5 additions & 5 deletions tests/run
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ local lscmd
if ffi.os == "Windows" then
lscmd = "cmd /c dir /b /s"

-- These tests produce spurious output due to a bug in LLVM on windows
table.insert(skip, "speed.t")
table.insert(skip, "class2.t")
-- FIXME: https://github.com/zdevito/terra/issues/401
table.insert(skip, "benchmark_fannkuchredux.t")
table.insert(skip, "class2.t")
table.insert(skip, "stdio.t")
table.insert(skip, "speed.t")
table.insert(skip, "benchmark_nbody.t")
-- FIXME: https://github.com/zdevito/terra/issues/404
table.insert(skip, "benchmark_fannkuchredux.t")
-- Disabled due to non-deterministic failures on certain branches: https://github.com/zdevito/terra/issues/404
table.insert(skip, "leaktest.t")
else
lscmd = "find . | cut -c 3-"
Expand Down
12 changes: 6 additions & 6 deletions tests/speed.t
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local c = terralib.includecstring [[
#include <stdio.h>
local C = terralib.includecstring [[
#include <stdlib.h>
]]
C.printf = terralib.externfunction("printf", terralib.types.funcpointer(rawstring,int,true))

terra doit(N : int64)
var cur,last = 1ULL,1ULL
Expand All @@ -13,18 +13,18 @@ end
terra main(argc : int, argv : &&int8)
var N = 4ULL
if argc == 2 then
N = c.atoi(argv[1])
N = C.atoi(argv[1])
end
var result = doit(N)
c.printf("%lld\n",result)
C.printf("%lld\n",result)
end

terra what()
return c.atoi("54")
return C.atoi("54")
end

local test = require("test")
print(what())
print(test.time( function() doit:compile() end))
print(test.time( function() doit(100000000) end))
print(test.time( function() terralib.saveobj("speed",{main = main}, (jit.os == "Windows" and "\\legacy_stdio_definitions.lib" or nil)) end))
print(test.time( function() terralib.saveobj("speed",{main = main}, (jit.os == "Windows" and {"\\legacy_stdio_definitions.lib"} or nil)) end))
12 changes: 12 additions & 0 deletions tests/stdio.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
C = terralib.includecstring[[
#include <stdio.h>
inline int testfunc(int a, int b) { return a + b; }]]

terra foobar() : int
var a : int = 5
C.printf("C: %i\n", C.testfunc(a, 9))
return C.testfunc(a, 9)
end
assert(foobar() == 14)

terralib.saveobj("stdio.exe", {main = foobar})

0 comments on commit 39764e6

Please sign in to comment.