Skip to content

Commit 293549f

Browse files
committed
Add support for FORTRAN code via the brand-new Flang front-end.
As part of the process, I've had to refactor the code to support more than just a dual C/C++ codebase. This probably isn't the best means of doing so, but it is sufficient for getting a working version of fortran compiling. Support for Dragonegg+gfortran is added as well, but it's completely untested. The code here is tested with the SPEC CPU2006 benchmark.
1 parent 2bdd2d5 commit 293549f

File tree

6 files changed

+56
-22
lines changed

6 files changed

+56
-22
lines changed

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
'wllvm-as = wllvm.as:main',
3434
'wllvm = wllvm.wllvm:main',
3535
'wllvm++ = wllvm.wllvmpp:main',
36+
'wfortran = wllvm.wfortran:main',
3637
'wllvm-sanity-checker = wllvm.sanity:main',
3738
'extract-bc = wllvm.extractor:main',
3839
],

wllvm/arglistfilter.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ def __init__(self, inputList, exactMatches={}, patternMatches={}):
213213
#
214214
defaultArgPatterns = {
215215
r'^.+\.(c|cc|cpp|C|cxx|i|s|S|bc)$' : (0, ArgumentListFilter.inputFileCallback),
216+
# FORTRAN file types
217+
r'^.+\.([fF](|[0-9][0-9]|or|OR|pp|PP))$' : (0, ArgumentListFilter.inputFileCallback),
216218
#iam: the object file recogition is not really very robust, object files
217219
# should be determined by their existance and contents...
218220
r'^.+\.(o|lo|So|so|po|a|dylib)$' : (0, ArgumentListFilter.objectFileCallback),

wllvm/compilers.py

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
_logger = logConfig(__name__)
1919

2020

21-
def wcompile(isCXX):
21+
def wcompile(mode):
2222
""" The workhorse, called from wllvm and wllvm++.
2323
"""
2424

@@ -27,13 +27,13 @@ def wcompile(isCXX):
2727
try:
2828
cmd = list(sys.argv)
2929
cmd = cmd[1:]
30-
builder = getBuilder(cmd, isCXX)
30+
builder = getBuilder(cmd, mode)
3131
rc = buildObject(builder)
3232

3333
if rc == 0 and not os.environ.get('WLLVM_CONFIGURE_ONLY', False):
3434
buildAndAttachBitcode(builder)
3535
except Exception as e:
36-
_logger.debug('%s: exception case: %s', "wllvm++" if isCXX else "wllvm", str(e))
36+
_logger.debug('%s: exception case: %s', mode, str(e))
3737

3838
return rc
3939

@@ -133,9 +133,9 @@ def attachBitcodePathToObject(bcPath, outFileName):
133133
sys.exit(-1)
134134

135135
class BuilderBase(object):
136-
def __init__(self, cmd, isCxx, prefixPath=None):
136+
def __init__(self, cmd, mode, prefixPath=None):
137137
self.cmd = cmd
138-
self.isCxx = isCxx
138+
self.mode = mode
139139

140140
# Used as prefix path for compiler
141141
if prefixPath:
@@ -158,15 +158,15 @@ def getBitcodeCompiler(self):
158158
return cc + ['-emit-llvm']
159159

160160
def getCompiler(self):
161-
if self.isCxx:
162-
cxx = os.getenv('LLVM_CXX_NAME')
163-
if cxx:
164-
return ['{0}{1}'.format(self.prefixPath, cxx)]
165-
return ['{0}clang++'.format(self.prefixPath)]
166-
cc = os.getenv('LLVM_CC_NAME')
167-
if cc:
168-
return ['{0}{1}'.format(self.prefixPath, cc)]
169-
return ['{0}clang'.format(self.prefixPath)]
161+
if self.mode == "wllvm++":
162+
env, prog = 'LLVM_CXX_NAME', 'clang++'
163+
elif self.mode == "wllvm":
164+
env, prog = 'LLVM_CC_NAME', 'clang'
165+
elif self.mode == "wfortran":
166+
env, prog = 'LLVM_F77_NAME', 'flang'
167+
else:
168+
raise Exception("Unknown mode {0}".format(self.mode))
169+
return ['{0}{1}'.format(self.prefixPath, os.getenv(env) or prog)]
170170

171171
def getBitcodeArglistFilter(self):
172172
return ClangBitcodeArgumentListFilter(self.cmd)
@@ -187,14 +187,20 @@ def getCompiler(self):
187187
if os.getenv('LLVM_GCC_PREFIX') is not None:
188188
pfx = os.getenv('LLVM_GCC_PREFIX')
189189

190-
if self.isCxx:
191-
return ['{0}{1}g++'.format(self.prefixPath, pfx)]
192-
return ['{0}{1}gcc'.format(self.prefixPath, pfx)]
190+
if self.mode == "wllvm++":
191+
mode = 'g++'
192+
elif self.mode == "wllvm":
193+
mode = 'gcc'
194+
elif self.mode == "wfortran":
195+
mode = 'gfortran'
196+
else:
197+
raise Exception("Unknown mode {0}".format(self.mode))
198+
return ['{0}{1}{2}'.format(self.prefixPath, pfx, mode)]
193199

194200
def getBitcodeArglistFilter(self):
195201
return ArgumentListFilter(self.cmd)
196202

197-
def getBuilder(cmd, isCxx):
203+
def getBuilder(cmd, mode):
198204
compilerEnv = 'LLVM_COMPILER'
199205
cstring = os.getenv(compilerEnv)
200206
pathPrefix = os.getenv(llvmCompilerPathEnv) # Optional
@@ -203,9 +209,9 @@ def getBuilder(cmd, isCxx):
203209
_logger.info('WLLVM compiler path prefix "%s"', pathPrefix)
204210

205211
if cstring == 'clang':
206-
return ClangBuilder(cmd, isCxx, pathPrefix)
212+
return ClangBuilder(cmd, mode, pathPrefix)
207213
elif cstring == 'dragonegg':
208-
return DragoneggBuilder(cmd, isCxx, pathPrefix)
214+
return DragoneggBuilder(cmd, mode, pathPrefix)
209215
elif cstring is None:
210216
errorMsg = ' No compiler set. Please set environment variable %s'
211217
_logger.critical(errorMsg, compilerEnv)

wllvm/wfortran.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python
2+
"""This is a wrapper around the real compiler.
3+
4+
It first invokes a real compiler to generate
5+
an object file. Then it invokes a bitcode
6+
compiler to generate a parallel bitcode file.
7+
It records the location of the bitcode in an
8+
ELF section of the object file so that it can be
9+
found later after all of the objects are
10+
linked into a library or executable.
11+
"""
12+
13+
import sys
14+
15+
from .compilers import wcompile
16+
17+
18+
def main():
19+
""" The entry point to wllvm.
20+
"""
21+
return wcompile("wfortran")
22+
23+
24+
if __name__ == '__main__':
25+
sys.exit(main())

wllvm/wllvm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
def main():
1919
""" The entry point to wllvm.
2020
"""
21-
return wcompile(False)
21+
return wcompile("wllvm")
2222

2323

2424
if __name__ == '__main__':

wllvm/wllvmpp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
def main():
1717
""" The entry point to wllvm++.
1818
"""
19-
return wcompile(True)
19+
return wcompile("wllvm++")
2020

2121

2222
if __name__ == '__main__':

0 commit comments

Comments
 (0)