| // Copyright 2014 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.devtools.build.lib.rules.cpp; |
| |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import java.util.Objects; |
| import java.util.Set; |
| |
| /** |
| * Holds information collected for .o bitcode files coming from a ThinLTO C(++) compilation under |
| * our control. Specifically, maps each bitcode file to the corresponding minimized bitcode file |
| * that can be used for the LTO indexing step, as well as to compile flags applying to that |
| * compilation that should also be applied to the LTO backend compilation invocation. |
| */ |
| public final class LtoCompilationContext { |
| static final LtoCompilationContext EMPTY = new LtoCompilationContext(ImmutableMap.of()); |
| |
| private final ImmutableMap<Artifact, BitcodeInfo> ltoBitcodeFiles; |
| |
| private LtoCompilationContext(ImmutableMap<Artifact, BitcodeInfo> ltoBitcodeFiles) { |
| this.ltoBitcodeFiles = Preconditions.checkNotNull(ltoBitcodeFiles); |
| } |
| |
| /** |
| * Class to hold information for a bitcode file produced by the compile action needed by the LTO |
| * indexing and backend actions. |
| */ |
| private static final class BitcodeInfo { |
| private final Artifact minimizedBitcode; |
| private final ImmutableList<String> copts; |
| |
| BitcodeInfo(Artifact minimizedBitcode, ImmutableList<String> copts) { |
| this.minimizedBitcode = minimizedBitcode; |
| this.copts = Preconditions.checkNotNull(copts); |
| } |
| |
| /** The minimized bitcode file produced by the compile and used by LTO indexing. */ |
| Artifact getMinimizedBitcode() { |
| return minimizedBitcode; |
| } |
| |
| /** |
| * The compiler flags used for the compile that should also be used when finishing compilation |
| * during the LTO backend. |
| */ |
| ImmutableList<String> getCopts() { |
| return copts; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } |
| if (o == null || getClass() != o.getClass()) { |
| return false; |
| } |
| BitcodeInfo that = (BitcodeInfo) o; |
| return minimizedBitcode.equals(that.minimizedBitcode) && copts.equals(that.copts); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(minimizedBitcode, copts); |
| } |
| } |
| |
| /** Builder for LtoCompilationContext. */ |
| public static class Builder { |
| private final ImmutableMap.Builder<Artifact, BitcodeInfo> ltoBitcodeFiles = |
| ImmutableMap.builder(); |
| |
| public Builder() {} |
| |
| public LtoCompilationContext build() { |
| ImmutableMap<Artifact, BitcodeInfo> map = ltoBitcodeFiles.build(); |
| if (map.isEmpty()) { |
| return LtoCompilationContext.EMPTY; |
| } |
| return new LtoCompilationContext(map); |
| } |
| |
| /** Adds a bitcode file with the corresponding minimized bitcode file and compiler flags. */ |
| void addBitcodeFile( |
| Artifact fullBitcode, Artifact minimizedBitcode, ImmutableList<String> copts) { |
| ltoBitcodeFiles.put(fullBitcode, new BitcodeInfo(minimizedBitcode, copts)); |
| } |
| |
| /** Adds in all bitcode files and associated info from another LtoCompilationContext object. */ |
| public void addAll(LtoCompilationContext ltoCompilationContext) { |
| this.ltoBitcodeFiles.putAll(ltoCompilationContext.ltoBitcodeFiles); |
| } |
| } |
| |
| /** Whether there is an entry for the given bitcode file. */ |
| public boolean containsBitcodeFile(Artifact fullBitcode) { |
| return ltoBitcodeFiles.containsKey(fullBitcode); |
| } |
| |
| /** |
| * Gets the minimized bitcode corresponding to the full bitcode file, or returns full bitcode if |
| * it doesn't exist. |
| */ |
| Artifact getMinimizedBitcodeOrSelf(Artifact fullBitcode) { |
| if (!containsBitcodeFile(fullBitcode)) { |
| return fullBitcode; |
| } |
| Artifact minimizedBitcode = ltoBitcodeFiles.get(fullBitcode).getMinimizedBitcode(); |
| // Will be null when the feature to use minimized bitcode is disabled. |
| if (minimizedBitcode == null) { |
| return fullBitcode; |
| } |
| return minimizedBitcode; |
| } |
| |
| /** |
| * Gets the compiler flags corresponding to the full bitcode file, or returns an empty list if it |
| * doesn't exist. |
| */ |
| public ImmutableList<String> getCopts(Artifact fullBitcode) { |
| if (!containsBitcodeFile(fullBitcode)) { |
| return ImmutableList.of(); |
| } |
| return ltoBitcodeFiles.get(fullBitcode).getCopts(); |
| } |
| |
| /** Whether the map of bitcode files is empty. */ |
| public boolean isEmpty() { |
| return ltoBitcodeFiles.isEmpty(); |
| } |
| |
| /** The set of bitcode files recorded in the map. */ |
| Set<Artifact> getBitcodeFiles() { |
| return ltoBitcodeFiles.keySet(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) { |
| return true; |
| } |
| return (o instanceof LtoCompilationContext) |
| && ltoBitcodeFiles.equals(((LtoCompilationContext) o).ltoBitcodeFiles); |
| } |
| |
| @Override |
| public int hashCode() { |
| return ltoBitcodeFiles.hashCode(); |
| } |
| } |