Source code for varats.experiments.vara.blame_report_experiment

"""
Implements the basic blame report experiment.

The experiment analyses a project with VaRA's blame analysis and generates a
BlameReport.
"""

import typing as tp
from pathlib import Path

import benchbuild.utils.actions as actions
from benchbuild import Project
from benchbuild.utils.cmd import mkdir, opt
from benchbuild.utils.requirements import Requirement, SlurmMem

import varats.experiments.vara.blame_experiment as BE
from varats.data.reports.blame_report import BlameReport as BR
from varats.experiment.experiment_util import (
    exec_func_with_pe_error_handler,
    VersionExperiment,
    wrap_unlimit_stack_size,
    create_default_compiler_error_handler,
    create_default_analysis_failure_handler,
)
from varats.experiment.wllvm import get_cached_bc_file_path, BCFileExtensions
from varats.report.report import FileStatusExtension as FSE
from varats.utils.settings import bb_cfg


[docs]class BlameReportGeneration(actions.Step): # type: ignore """Analyse a project with VaRA and generate a BlameReport.""" NAME = "BlameReportGeneration" DESCRIPTION = "Analyses the bitcode with -vara-BR of VaRA." RESULT_FOLDER_TEMPLATE = "{result_dir}/{project_dir}" def __init__( self, project: Project, ): super().__init__(obj=project, action_fn=self.analyze)
[docs] def analyze(self) -> actions.StepResult: """ This step performs the actual analysis with the correct command line flags. Flags used: * -vara-BR: to run a commit flow report * -yaml-report-outfile=<path>: specify the path to store the results """ if not self.obj: return project = self.obj # Add to the user-defined path for saving the results of the # analysis also the name and the unique id of the project of every # run. vara_result_folder = self.RESULT_FOLDER_TEMPLATE.format( result_dir=str(bb_cfg()["varats"]["outfile"]), project_dir=str(project.name) ) mkdir("-p", vara_result_folder) for binary in project.binaries: result_file = BR.get_file_name( project_name=str(project.name), binary_name=binary.name, project_version=project.version_of_primary, project_uuid=str(project.run_uuid), extension_type=FSE.Success ) opt_params = [ "-vara-BD", "-vara-BR", "-vara-init-commits", "-vara-use-phasar", f"-vara-report-outfile={vara_result_folder}/{result_file}", get_cached_bc_file_path( project, binary, [BCFileExtensions.NO_OPT, BCFileExtensions.TBAA] ) ] run_cmd = opt[opt_params] run_cmd = wrap_unlimit_stack_size(run_cmd) exec_func_with_pe_error_handler( run_cmd, create_default_analysis_failure_handler( project, BR, Path(vara_result_folder) ) )
[docs]class BlameReportExperiment(VersionExperiment): """Generates a commit flow report (CFR) of the project(s) specified in the call.""" NAME = "GenerateBlameReport" REPORT_TYPE = BR REQUIREMENTS: tp.List[Requirement] = [SlurmMem("250G")]
[docs] def actions_for_project(self, project: Project) -> tp.List[actions.Step]: """ Returns the specified steps to run the project(s) specified in the call in a fixed order. Args: project: to analyze """ # Try, to build the project without optimizations to get more precise # blame annotations. Note: this does not guarantee that a project is # build without optimizations because the used build tool/script can # still add optimizations flags after the experiment specified cflags. project.cflags += ["-O1", "-Xclang", "-disable-llvm-optzns", "-g0"] bc_file_extensions = [BCFileExtensions.NO_OPT, BCFileExtensions.TBAA] BE.setup_basic_blame_experiment( self, project, BR, BlameReportGeneration.RESULT_FOLDER_TEMPLATE ) analysis_actions = BE.generate_basic_blame_experiment_actions( project, bc_file_extensions, extraction_error_handler=create_default_compiler_error_handler( project, self.REPORT_TYPE ) ) analysis_actions.append(BlameReportGeneration(project)) analysis_actions.append(actions.Clean(project)) return analysis_actions