# Include LLVM common makefile.
include $(LEVEL)/Makefile.common
+
+CXX.Flags += -std=c++11 -Wextra -Werror -Wno-error=unused-parameter
+
+CPP.Defines += -DALLOW_TEXT_ASM=1 -DALLOW_DUMP=1 -DALLOW_LLVM_CL=1 \
+ -DALLOW_LLVM_IR=1 -DALLOW_LLVM_IR_AS_INPUT=1
+
OPTLEVEL = -O2
endif
+# The list of CXX defines that are dependent on build parameters.
+CXX_DEFINES =
+
+ifdef MINIMAL
+ OBJDIR := $(OBJDIR)+Min
+ CXX_DEFINES += -DALLOW_TEXT_ASM=0 -DALLOW_DUMP=0 -DALLOW_LLVM_CL=0 \
+ -DALLOW_LLVM_IR=0 -DALLOW_LLVM_IR_AS_INPUT=0
+else
+ CXX_DEFINES += -DALLOW_TEXT_ASM=1 -DALLOW_DUMP=1 -DALLOW_LLVM_CL=1 \
+ -DALLOW_LLVM_IR=1 -DALLOW_LLVM_IR_AS_INPUT=1
+endif
+
ifdef NOASSERT
ASSERTIONS = -DNDEBUG
else
CXX := CCACHE_CPP2=yes $(CCACHE) $(CLANG_PATH)/clang++
CXXFLAGS := $(LLVM_CXXFLAGS) -std=c++11 -Wall -Wextra -Werror -fno-rtti \
- -fno-exceptions $(OPTLEVEL) $(ASSERTIONS) -g $(HOST_FLAGS) \
- -Wno-error=unused-parameter -I$(LIBCXX_INSTALL_PATH)/include/c++/v1
+ -fno-exceptions $(OPTLEVEL) $(ASSERTIONS) $(CXX_DEFINES) -g \
+ $(HOST_FLAGS) -Wno-error=unused-parameter \
+ -I$(LIBCXX_INSTALL_PATH)/include/c++/v1
LDFLAGS := $(HOST_FLAGS) -L$(LIBCXX_INSTALL_PATH)/lib
SRCS= \
# Keep all the first target so it's the default.
all: $(OBJDIR)/llvm2ice make_symlink
-make_symlink: $(OBJDIR)/llvm2ice
- rm -f llvm2ice
+make_symlink: $(OBJDIR)/llvm2ice $(OBJDIR)/llvm2ice.build_atts
+ rm -rf llvm2ice llvm2ice.build_atts
ln -s $(OBJDIR)/llvm2ice
+ ln -s $(OBJDIR)/llvm2ice.build_atts
.PHONY: all make_symlink
+# TODO(kschimpf): Fix python scripts to directly get build attributes
+# rather than generating $(OBJDIR)/llvm2ice.build_atts.
$(OBJDIR)/llvm2ice: $(OBJS)
$(CXX) $(LDFLAGS) -o $@ $^ $(LLVM_LDFLAGS) -ldl \
-Wl,-rpath=$(abspath $(LIBCXX_INSTALL_PATH)/lib)
+ $@ --build-atts > $@.build_atts
# TODO: Be more precise than "*.h" here and elsewhere.
$(OBJS): $(OBJDIR)/%.o: src/%.cpp src/*.h src/*.def
$(CLANG_FORMAT_DIFF) -p1 -style=LLVM -i
clean:
- rm -rf llvm2ice *.o build/
+ rm -rf llvm2ice llvm2ice.build_atts *.o $(OBJDIR)
+
+clean-all: clean
+ rm -rf build/
--- /dev/null
+#!/usr/bin/env python2
+
+import argparse
+import os
+import sys
+
+from utils import shellcmd
+
+def GetFileAttributes(Filename):
+ """Returns the set of names contained in file named Filename.
+ """
+ if not os.path.isfile(Filename):
+ raise RuntimeError("Can't open: %s" % Filename)
+ with open(Filename, 'r') as f:
+ return f.read().split()
+
+def HasFileAttributes(Filename, Attributes):
+ """Returns true if the set of names in Attributes also appear
+ in the set of names contained in file named Filename.
+ """
+ return set(Attributes) <= set(GetFileAttributes(Filename))
+
+def main():
+ """Run the specified command only if attributes are defined.
+
+ Check if the fset of attributes (i.e. names), contained in FILE,
+ contains the attributes defined by --att=ATTRIBUTE arguments. If
+ so, runs in a shell the command defined by the remaining
+ arguments.
+ """
+ argparser = argparse.ArgumentParser(
+ description=' ' + main.__doc__,
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ argparser.add_argument('file', metavar='FILE',
+ help='File defining attributes to check against.')
+ argparser.add_argument('--att', required=False, default=[],
+ action='append', metavar='ATTRIBUTE',
+ help='Attribute to check. May be repeated.')
+ argparser.add_argument('--echo-cmd', required=False,
+ action='store_true',
+ help='Trace the command before running.')
+ argparser.add_argument('--command', nargs=argparse.REMAINDER,
+ help='Command to run if attributes found.')
+
+ args = argparser.parse_args()
+
+ # Quit early if no command to run.
+ if not args.command:
+ raise RuntimeError("No command argument(s) specified for ifatts")
+
+ if HasFileAttributes(args.file, args.att):
+ stdout_result = shellcmd(args.command, echo=args.echo_cmd)
+ if not args.echo_cmd:
+ sys.stdout.write(stdout_result)
+
+if __name__ == '__main__':
+ main()
+ sys.exit(0)
namespace {
+const char *TargetArchName[] = {
+#define X(tag, str) str ,
+ TARGETARCH_TABLE
+#undef X
+};
+
// Show tags match between ICETYPE_TABLE and ICETYPE_PROPS_TABLE.
// Define a temporary set of enum values based on ICETYPE_TABLE
} // end anonymous namespace
+const char *targetArchString(const TargetArch Arch) {
+ size_t Index = static_cast<size_t>(Arch);
+ if (Index < TargetArch_NUM)
+ return TargetArchName[Index];
+ llvm_unreachable("Invalid target arch for targetArchString");
+ return "???";
+}
+
size_t typeWidthInBytes(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
#ifndef SUBZERO_SRC_ICETYPES_DEF
#define SUBZERO_SRC_ICETYPES_DEF
+#define TARGETARCH_TABLE \
+ /* enum value, printable string */ \
+ X(Target_X8632, "x86-32") \
+ X(Target_X8664, "x86-64") \
+ X(Target_ARM32, "arm32") \
+ X(Target_ARM64, "arm64") \
+//#define X(tag, str)
+
#define ICETYPE_TABLE \
/* enum value, size, align, # elts, element type, printable string */ \
/* (size and alignment in bytes) */ \
};
enum TargetArch {
- Target_X8632,
- Target_X8664,
- Target_ARM32,
- Target_ARM64
+#define X(tag, str) tag,
+ TARGETARCH_TABLE
+#undef X
+ TargetArch_NUM
};
+const char *targetArchString(TargetArch Arch);
+
+inline Ostream &operator<<(Ostream &Stream, TargetArch Arch) {
+ return Stream << targetArchString(Arch);
+}
+
enum OptLevel {
Opt_m1,
Opt_0,
#include <fstream>
#include <iostream>
+#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
"exit-success", cl::desc("Exit with success status, even if errors found"),
cl::init(false));
+static cl::opt<bool> GenerateBuildAtts(
+ "build-atts", cl::desc("Generate list of build attributes associated with "
+ "this executable."),
+ cl::init(false));
+
static int GetReturnValue(int Val) {
if (AlwaysExitSuccess)
return 0;
return Val;
}
+static struct {
+ const char *FlagName;
+ int FlagValue;
+} ConditionalBuildAttributes[] = {
+ { "text_asm", ALLOW_TEXT_ASM },
+ { "dump", ALLOW_DUMP },
+ { "llvm_cl", ALLOW_LLVM_CL },
+ { "llvm_ir", ALLOW_LLVM_IR },
+ { "llvm_ir_as_input", ALLOW_LLVM_IR_AS_INPUT }
+};
+
+// Validates values of build attributes. Prints them to Stream if
+// Stream is non-null.
+static void ValidateAndGenerateBuildAttributes(raw_os_ostream *Stream) {
+
+ if (Stream)
+ *Stream << TargetArch << "\n";
+
+ for (size_t i = 0; i < array_lengthof(ConditionalBuildAttributes); ++i) {
+ switch (ConditionalBuildAttributes[i].FlagValue) {
+ case 0:
+ if (Stream)
+ *Stream << "no_" << ConditionalBuildAttributes[i].FlagName << "\n";
+ break;
+ case 1:
+ if (Stream)
+ *Stream << "allow_" << ConditionalBuildAttributes[i].FlagName << "\n";
+ break;
+ default: {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Flag " << ConditionalBuildAttributes[i].FlagName
+ << " must be defined as 0/1. Found: "
+ << ConditionalBuildAttributes[i].FlagValue;
+ report_fatal_error(StrBuf.str());
+ }
+ }
+ }
+}
+
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv);
raw_os_ostream *Os =
new raw_os_ostream(OutputFilename == "-" ? std::cout : Ofs);
Os->SetUnbuffered();
+
+ ValidateAndGenerateBuildAttributes(GenerateBuildAtts ? Os : nullptr);
+ if (GenerateBuildAtts)
+ return GetReturnValue(0);
+
std::ofstream Lfs;
if (LogFilename != "-") {
Lfs.open(LogFilename.c_str(), std::ofstream::out);
Ice::GlobalContext Ctx(Ls, Os, VMask, TargetArch, OptLevel, TestPrefix,
Flags);
+
Ice::TimerMarker T(Ice::TimerStack::TT_szmain, &Ctx);
int ErrorStatus = 0;
+# -*- Python -*-
# Taken from utils/lit/tests in the LLVM tree and hacked together to support
# our tests.
-
-# -*- Python -*-
+#
+# Note: This configuration has simple commands to run Subzero's translator.
+# They have the form %X2i (i.e. %p2i, %l2i, and %lc2i) where X is defined
+# as follows:
+#
+# p : Run Subzero's translator, building ICE from PNaCl bitcode directly.
+# l : Run Subzero's translator, converting the .ll file to a PNaCl bitcode
+# file, reading in the bitcode file and generating LLVM IR, and
+# then convert LLVM IR to ICE IR.
+# lc : Run Subzero's translator, directly parsing the .ll file into LLVM IR,
+# and then convert it to ICE IR.
+#
+# These commands can be used in RUN lines by FileCheck. If the Subzero
+# build being tested lacks any required attributes (e.g., the ability
+# to parse .ll files), the command will simply return successfully,
+# generating no output. This allows translation tests to be able to
+# conditionally test the translator, based on the translator built.
+#
+# This conditional handling of translation introduces potential problems
+# when the output is piped to another command on a RUN line. Executables
+# like FileCheck expect non-empty input.
+#
+# To handle the problem that the pipe is conditional, any command that
+# doesn't accept empty input should be prefixed by a corresponding
+# %ifX (i.e. %p2i, %ifl, or %ifpc). Note: %p2i should always work, and
+# hence %ifp is not necessary (i.e. it is a nop).
+#
+# If you need to check other build attributes (other than the
+# existence of %l2i and %lc2i), you can use the %if command (which is
+# a short hand for using pydir/ifatts.py).
import os
import re
sys.path.insert(0, 'pydir')
from utils import FindBaseNaCl
+from ifatts import GetFileAttributes
# name: The name of this test suite.
config.name = 'subzero'
# the llvmbintools list.
llvmbinpath = os.path.abspath(os.environ.get('LLVM_BIN_PATH'))
-# Finding Subzero tools
+# Define the location of the llvm2ice tool.
llvm2icetool = os.path.join(bin_root, 'llvm2ice')
-
-# Convert LLVM source to PNaCl bitcode, read using the
-# Subzero bitcode reader, and then translate.
-config.substitutions.append(
- ('%p2i', ' '.join([os.path.join(pydir, 'run-llvm2ice.py'),
- '--llvm2ice', llvm2icetool,
- '--llvm-bin-path', llvmbinpath
- ])))
-
-# Convert LLVM source to PNaCl bitcode, read using the PNaCl bitcode reader,
-# convert to ICE using the ICE Converter, and then translate.
-# TODO(kschimpf) Deprecated, remove once p2i working.
-config.substitutions.append(
- ('%l2i', ' '.join([os.path.join(pydir, 'run-llvm2ice.py'),
- '--llvm', '--llvm2ice', llvm2icetool,
- '--llvm-bin-path', llvmbinpath
- ])))
-
-# Read LLVM source, convert to ICE using the ICE converter, and then translate.
-# Note: l2i is preferred over lc2i, since it uses PNaCl bitcode.
-# TODO(kschimpf) Deprecated, remove once p2i working.
-config.substitutions.append(
- ('%lc2i', ' '.join([os.path.join(pydir, 'run-llvm2ice.py'),
- '--llvm-source', '--llvm2ice', llvm2icetool,
- '--llvm-bin-path', llvmbinpath
- ])))
+llvm2icetoolatts = os.path.join(bin_root, 'llvm2ice.build_atts')
+
+# Add build attributes of llvm2ice tool to the set of available features.
+config.available_features.update(GetFileAttributes(llvm2icetoolatts))
+
+# Base command for testing build attributes
+if_atts_base = [os.path.join(pydir, 'ifatts.py'), llvm2icetoolatts]
+if_atts_cmd = if_atts_base + ['--command']
+ifl2i_atts_cmd = if_atts_base + ['--att=allow_llvm_ir', '--command']
+iflc2i_atts_cmd = if_atts_base + ['--att=allow_llvm_ir',
+ '--att=allow_llvm_ir_as_input',
+ '--command']
+
+# Base command for running llvm2ice
+llvm2ice_cmd = [os.path.join(pydir, 'run-llvm2ice.py'),
+ '--llvm2ice', llvm2icetool,
+ '--llvm-bin-path', llvmbinpath]
+
+# Run commands only if corresponding build attributes apply, including
+# for each compiler setup.
+config.substitutions.append(('%ifp', ' '))
+config.substitutions.append(('%iflc', ' '.join(iflc2i_atts_cmd)))
+config.substitutions.append(('%ifl', ' '.join(ifl2i_atts_cmd)))
+config.substitutions.append(('%if', ' '.join(if_atts_cmd)))
+
+# Translate LLVM source for each compiler setup.
+config.substitutions.append(('%p2i', ' '.join(llvm2ice_cmd)))
+config.substitutions.append(('%l2i', ' '.join(ifl2i_atts_cmd + llvm2ice_cmd
+ + ['--llvm'])))
+config.substitutions.append(('%lc2i', ' '.join(iflc2i_atts_cmd + llvm2ice_cmd
+ + ['--llvm-source'])))
config.substitutions.append(('%llvm2ice', llvm2icetool))
config.substitutions.append(('%szdiff', os.path.join(pydir, 'szdiff.py')))
; This test depends to some degree on the stability of "--verbose
; addropt" output format.
+; REQUIRES: x86-32
+; REQUIRES: allow_dump
; RUN: %p2i -i %s --args -O2 --verbose addropt | FileCheck %s
declare i32 @_calloc_r(i32, i32, i32)
; This checks to ensure that Subzero aligns spill slots.
; TODO(kschimpf) Find out why lc2i needed.
+; REQUIRES: allow_llvm_ir_as_input
; RUN: %lc2i -i %s --args --verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s
; ebp-based frames.
; TODO(kschimpf) Find out why lc2i is needed.
+; REQUIRES: allow_llvm_ir_as_input
; RUN: %lc2i -i %s --args -Om1 --target=x8632 --verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s
; variables.
; TODO(kschimpf) find out why lc2i is needed.
-; RUN: %lc2i -i %s --args --verbose inst | FileCheck %s
+; REQUIRES: allow_llvm_ir_as_input
+; RUN: %lc2i -i %s --args --verbose inst | %iflc FileCheck %s
; RUN: %lc2i -i %s --args --verbose none | FileCheck --check-prefix=ERRORS %s
; Note: PNaCl ABI Doesn't allow external globals. Hence, not tested.
; Tests if we handle global variables with relocation initializers.
; Test that we handle it in the ICE converter.
-; RUN: %lc2i -i %s --args -verbose inst | FileCheck %s
+; RUN: %lc2i -i %s --args -verbose inst | %iflc FileCheck %s
; Test that we handle it using Subzero's bitcode reader.
; RUN: %p2i -i %s --args -verbose inst | FileCheck %s
; TODO(kschimpf) Find out why lc2i is needed.
; RUN: %lc2i -i %s --args -O2 --verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
-; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s
+; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \
+; RUN: | %iflc FileCheck %s
; RUN: %p2i -i %s --args -O2 --verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \
; RUN: | FileCheck --check-prefix=CHECKO2 %s
; RUN: %lc2i -i %s --args -Om1 --verbose none \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
-; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s
-; RUN: %p2i -i %s --args --verbose none | FileCheck --check-prefix=ERRORS %s
+; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - \
+; RUN: | %iflc FileCheck %s
+; RUN: %p2i -i %s --args --verbose none \
+; RUN: | FileCheck --check-prefix=ERRORS %s
declare i8 @llvm.nacl.atomic.load.i8(i8*, i32)
declare i16 @llvm.nacl.atomic.load.i16(i16*, i32)
; compare/branch fusing.
; TODO(kschimpf) Find out why lc2i must be used.
+; REQUIRES: allow_llvm_ir_as_input
; RUN: %lc2i -i %s --args -O2 --verbose none --phi-edge-split=0 \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
; RUN: | llvm-objdump -d -symbolize -x86-asm-syntax=intel - | FileCheck %s
; with struct members.
; TODO(kschimpf) Find out why lc2i is needed.
+; REQUIRES: allow_llvm_ir_as_input
; RUN: %lc2i -i %s --args --verbose inst | FileCheck %s
; RUN: %lc2i -i %s --args --verbose none | FileCheck --check-prefix=ERRORS %s
; Tests if we can read binary operators.
; RUN: %p2i -i %s --insts | FileCheck %s
+; RUN: %l2i -i %s --insts | %ifl FileCheck %s
+; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
; TODO(kschimpf): add i8/i16. Needs bitcasts.
; allow externally defined global variables. Hence, this test can only
; work if we read LLVM IR source, and convert to to ICE.
+; REQUIRES: allow_llvm_ir_as_input
; RUN: %lc2i -i %s --insts --args --allow-uninitialized-globals | FileCheck %s
; RUN: %lc2i -i %s --insts --args --allow-uninitialized-globals \
; RUN: -prefix Subzero_ | FileCheck --check-prefix=CROSS %s
; Test of global initializers.
-; Check that we generate proper global initializers.
-; RUN: %l2i -i %s --insts | FileCheck %s
; RUN: %p2i -i %s --insts | FileCheck %s
+; RUN: %l2i -i %s --insts | %ifl FileCheck %s
+; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
@PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
; CHECK: @PrimitiveInit = internal global [4 x i8] c"\1B\00\00\00", align 4
; Tests if we handle global variables with relocation initializers.
-; Test that we handle it in the ICE converter.
-; RUN: %lc2i -i %s --insts | FileCheck %s
-
-; Test that we handle it using Subzero's bitcode reader.
; RUN: %p2i -i %s --insts | FileCheck %s
+; RUN: %l2i -i %s --insts | %ifl FileCheck %s
+; RUN: %lc2i -i %s --insts | %iflc FileCheck %s
@bytes = internal global [7 x i8] c"abcdefg"
; CHECK: @bytes = internal global [7 x i8] c"abcdefg"
; Tests that we name unnamed global addresses.
-; Check that the ICE converter handles renaming correctly.
-; RUN: %l2i --no-local-syms -i %s --insts | FileCheck %s
+; Check that Subzero's bitcode reader handles renaming correctly.
+; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s
+; RUN: %l2i --no-local-syms -i %s --insts | %ifl FileCheck %s
; RUN: %l2i --no-local-syms -i %s --insts --args --exit-success \
; RUN: -default-function-prefix=h -default-global-prefix=g \
-; RUN: | FileCheck --check-prefix=BAD %s
-
-; Check that Subzero's bitcode reader handles renaming correctly.
-; RUN: %p2i --no-local-syms -i %s --insts | FileCheck %s
+; RUN: | %ifl FileCheck --check-prefix=BAD %s
; RUN: %p2i --no-local-syms -i %s --insts --args --exit-success \
; RUN: -default-function-prefix=h -default-global-prefix=g \