brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · dcd1541 Raw
166 lines · python
1#!/usr/bin/env python32 3"""This script verifies expression folding.4It compiles a source file with '-fdebug-dump-symbols'5and looks for parameter declarations to check6they have been folded as expected.7To check folding of an expression EXPR,8the fortran program passed to this script9must contain the following:10 11  logical, parameter :: test_x = <compare EXPR to expected value>12 13This script will test that all parameter14with a name starting with "test_"15have been folded to .true.16For instance, acos folding can be tested with:17 18  real(4), parameter :: res_acos = acos(0.5_4)19  real(4), parameter :: exp_acos = 1.04720  logical, parameter :: test_acos = abs(res_acos - exp_acos).LE.(0.001_4)21 22There are two kinds of failure:23  - test_x is folded to .false..24    This means the expression was folded25    but the value is not as expected.26  - test_x is not folded (it is neither .true. nor .false.).27    This means the compiler could not fold the expression.28 29Parameters:30    sys.argv[1]: a source file with contains the input and expected output31    sys.argv[2]: the Flang frontend driver32    sys.argv[3:]: Optional arguments to the Flang frontend driver"""33 34import os35import sys36import tempfile37import re38import subprocess39 40from difflib import unified_diff41from pathlib import Path42 43 44def check_args(args):45    """Verifies that the number is arguments passed is correct."""46    if len(args) < 3:47        print(f"Usage: {args[0]} <fortran-source> <flang-command>")48        sys.exit(1)49 50 51def set_source(source):52    """Sets the path to the source files."""53    if not Path(source).is_file():54        print(f"File not found: {src}")55        sys.exit(1)56    return Path(source)57 58 59def set_executable(exe):60    """Sets the path to the Flang frontend driver."""61    if not Path(exe).is_file():62        print(f"Flang was not found: {exe}")63        sys.exit(1)64    return str(Path(exe))65 66 67check_args(sys.argv)68cwd = os.getcwd()69srcdir = set_source(sys.argv[1]).resolve()70with open(srcdir, "r", encoding="utf-8") as f:71    src = f.readlines()72src1 = ""73src2 = ""74src3 = ""75src4 = ""76messages = ""77actual_warnings = ""78expected_warnings = ""79warning_diffs = ""80 81flang_fc1 = set_executable(sys.argv[2])82flang_fc1_args = sys.argv[3:]83flang_fc1_options = ""84LIBPGMATH = os.getenv("LIBPGMATH")85if LIBPGMATH:86    flang_fc1_options = ["-fdebug-dump-symbols", "-DTEST_LIBPGMATH"]87    print("Assuming libpgmath support")88else:89    flang_fc1_options = ["-fdebug-dump-symbols"]90    print("Not assuming libpgmath support")91 92cmd = [flang_fc1, *flang_fc1_args, *flang_fc1_options, str(srcdir)]93with tempfile.TemporaryDirectory() as tmpdir:94    proc = subprocess.run(95        cmd,96        stdout=subprocess.PIPE,97        stderr=subprocess.PIPE,98        check=True,99        universal_newlines=True,100        cwd=tmpdir,101    )102    src1 = proc.stdout103    messages = proc.stderr104 105for line in src1.split("\n"):106    m = re.search(r"(\w*)(?=, PARAMETER).*init:(.*)", line)107    if m:108        src2 += f"{m.group(1)} {m.group(2)}\n"109 110for line in src2.split("\n"):111    m = re.match(r"test_*", line)112    if m:113        src3 += f"{m.string}\n"114 115for passed_results, line in enumerate(src3.split("\n")):116    m = re.search(r"\.false\._.$", line)117    if m:118        src4 += f"{line}\n"119 120for line in messages.split("\n"):121    m = re.search(r"[^:]*:(\d*):\d*: (.*)", line)122    if m:123        actual_warnings += f"{m.group(1)}: {m.group(2)}\n"124 125passed_warnings = 0126warnings = []127for i, line in enumerate(src, 1):128    m = re.search(r"(?:!WARN:)(.*)", line)129    if m:130        warnings.append(m.group(1))131        continue132    if warnings:133        for x in warnings:134            passed_warnings += 1135            expected_warnings += f"{i}:{x}\n"136        warnings = []137 138for line in unified_diff(139    actual_warnings.split("\n"), expected_warnings.split("\n"), n=0140):141    line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line)142    line = re.sub(r"(^\+)(\d+:)", r"\nexpect at \g<2>", line)143    warning_diffs += line144 145if src4 or warning_diffs:146    print("Folding test failed:")147    # Prints failed tests, including parameters with the same148    # suffix so that more information can be obtained by declaring149    # expected_x and result_x150    if src4:151        for line in src4.split("\n"):152            m = re.match(r"test_(\w+)", line)153            if m:154                for line in src2.split("\n"):155                    if m.group(1) in line:156                        print(line)157    if warning_diffs:158        print(warning_diffs)159    print()160    print("FAIL")161    sys.exit(1)162else:163    print()164    print(f"All {passed_results+passed_warnings} tests passed")165    print("PASS")166