Skip to content

Commit b45a08d

Browse files
committed
Merge branch 'users/meinersbur/flang_runtime_FLANG_INCLUDE_RUNTIME' into users/meinersbur/flang_runtime_flang_rt
2 parents a446bad + 1fbd2c5 commit b45a08d

File tree

31 files changed

+1221
-180
lines changed

31 files changed

+1221
-180
lines changed

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
#include "llvm/Support/ErrorHandling.h"
7575
#include "llvm/Support/GraphWriter.h"
7676
#include "llvm/Support/SaveAndRestore.h"
77+
#include "llvm/Support/TimeProfiler.h"
7778
#include "llvm/Support/raw_ostream.h"
7879
#include <cassert>
7980
#include <cstdint>
@@ -1031,6 +1032,7 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
10311032
const LocationContext *LC,
10321033
const Stmt *DiagnosticStmt,
10331034
ProgramPoint::Kind K) {
1035+
llvm::TimeTraceScope TimeScope("ExprEngine::removeDead");
10341036
assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
10351037
ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt))
10361038
&& "PostStmt is not generally supported by the SymbolReaper yet");

clang/lib/StaticAnalyzer/Core/RegionStore.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
3030
#include "llvm/ADT/ImmutableMap.h"
3131
#include "llvm/ADT/STLExtras.h"
32+
#include "llvm/Support/TimeProfiler.h"
3233
#include "llvm/Support/raw_ostream.h"
3334
#include <optional>
3435
#include <utility>
@@ -112,6 +113,13 @@ class BindingKey {
112113

113114
LLVM_DUMP_METHOD void dump() const;
114115
};
116+
117+
std::string locDescr(Loc L) {
118+
std::string S;
119+
llvm::raw_string_ostream OS(S);
120+
L.dumpToStream(OS);
121+
return OS.str();
122+
}
115123
} // end anonymous namespace
116124

117125
BindingKey BindingKey::Make(const MemRegion *R, Kind k) {
@@ -2408,6 +2416,8 @@ StoreRef RegionStoreManager::killBinding(Store ST, Loc L) {
24082416

24092417
RegionBindingsRef
24102418
RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
2419+
llvm::TimeTraceScope TimeScope("RegionStoreManager::bind",
2420+
[&L]() { return locDescr(L); });
24112421
// We only care about region locations.
24122422
auto MemRegVal = L.getAs<loc::MemRegionVal>();
24132423
if (!MemRegVal)
@@ -2514,6 +2524,8 @@ RegionBindingsRef
25142524
RegionStoreManager::bindArray(RegionBindingsConstRef B,
25152525
const TypedValueRegion* R,
25162526
SVal Init) {
2527+
llvm::TimeTraceScope TimeScope("RegionStoreManager::bindArray",
2528+
[R]() { return R->getDescriptiveName(); });
25172529

25182530
const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType()));
25192531
QualType ElementTy = AT->getElementType();
@@ -2578,6 +2590,8 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B,
25782590
RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
25792591
const TypedValueRegion* R,
25802592
SVal V) {
2593+
llvm::TimeTraceScope TimeScope("RegionStoreManager::bindVector",
2594+
[R]() { return R->getDescriptiveName(); });
25812595
QualType T = R->getValueType();
25822596
const VectorType *VT = T->castAs<VectorType>(); // Use castAs for typedefs.
25832597

@@ -2700,6 +2714,8 @@ std::optional<RegionBindingsRef> RegionStoreManager::tryBindSmallStruct(
27002714
RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
27012715
const TypedValueRegion *R,
27022716
SVal V) {
2717+
llvm::TimeTraceScope TimeScope("RegionStoreManager::bindStruct",
2718+
[R]() { return R->getDescriptiveName(); });
27032719
QualType T = R->getValueType();
27042720
assert(T->isStructureOrClassType());
27052721

@@ -2818,6 +2834,8 @@ RegionBindingsRef
28182834
RegionStoreManager::bindAggregate(RegionBindingsConstRef B,
28192835
const TypedRegion *R,
28202836
SVal Val) {
2837+
llvm::TimeTraceScope TimeScope("RegionStoreManager::bindAggregate",
2838+
[R]() { return R->getDescriptiveName(); });
28212839
// Remove the old bindings, using 'R' as the root of all regions
28222840
// we will invalidate. Then add the new binding.
28232841
return removeSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core %s -ftime-trace=%t.raw.json -ftime-trace-granularity=0 -verify
2+
// RUN: %python -c 'import json, sys; print(json.dumps(json.load(sys.stdin), indent=4))' < %t.raw.json > %t.formatted.json
3+
// RUN: FileCheck --input-file=%t.formatted.json --check-prefix=CHECK %s
4+
5+
// CHECK: "name": "RegionStoreManager::bindArray",
6+
// CHECK-NEXT: "args": {
7+
//
8+
// The below does not necessarily follow immediately,
9+
// depending on what parts of the array are initialized first.
10+
//
11+
// CHECK: "detail": "'arr[0][1]'"
12+
// CHECK-NEXT: }
13+
//
14+
// CHECK: "detail": "'arr[0]'"
15+
// CHECK-NEXT: }
16+
//
17+
// CHECK: "detail": "'arr'"
18+
// CHECK-NEXT: }
19+
20+
int f() {
21+
int arr[2][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
22+
return arr[1][0][1];
23+
}
24+
// expected-no-diagnostics
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core %s -ftime-trace=%t.raw.json -ftime-trace-granularity=0 -verify
2+
// RUN: %python -c 'import json, sys; print(json.dumps(json.load(sys.stdin), indent=4))' < %t.raw.json > %t.formatted.json
3+
// RUN: FileCheck --input-file=%t.formatted.json --check-prefix=CHECK %s
4+
5+
// The trace file is rather large, but it should contain at least one scope for removeDead:
6+
//
7+
// CHECK: "name": "ExprEngine::removeDead"
8+
9+
bool coin();
10+
int f() {
11+
int x = 0;
12+
int y = 0;
13+
while (coin()) {
14+
x = 1;
15+
}
16+
return x / y; // expected-warning{{Division by zero}}
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Verify the ELF packaging of OpenMP SPIR-V device images.
2+
// REQUIRES: system-linux
3+
// REQUIRES: spirv-tools
4+
// RUN: mkdir -p %t_tmp
5+
// RUN: cd %t_tmp
6+
// RUN: %clangxx -fopenmp -fopenmp-targets=spirv64-intel -nogpulib -c -o %t_clang-linker-wrapper-spirv-elf.o %s
7+
// RUN: not clang-linker-wrapper -o a.out %t_clang-linker-wrapper-spirv-elf.o --save-temps --linker-path=ld
8+
// RUN: clang-offload-packager --image=triple=spirv64-intel,kind=openmp,file=%t.elf %t_tmp/a.out.openmp.image.wrapper.o
9+
// RUN: llvm-readelf -t %t.elf | FileCheck -check-prefix=CHECK-SECTION %s
10+
// RUN: llvm-readelf -n %t.elf | FileCheck -check-prefix=CHECK-NOTES %s
11+
12+
// CHECK-SECTION: .note.inteloneompoffload
13+
// CHECK-SECTION: __openmp_offload_spirv_0
14+
15+
// CHECK-NOTES-COUNT-3: INTELONEOMPOFFLOAD
16+
int main(int argc, char** argv) {
17+
return 0;
18+
}

clang/test/Tooling/lit.local.cfg

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
if not config.root.clang_staticanalyzer:
22
config.unsupported = True
3+
4+
if config.spirv_tools_tests:
5+
config.available_features.add("spirv-tools")
6+
config.substitutions.append(("spirv-dis", os.path.join(config.llvm_tools_dir, "spirv-dis")))
7+
config.substitutions.append(("spirv-val", os.path.join(config.llvm_tools_dir, "spirv-val")))
8+
config.substitutions.append(("spirv-as", os.path.join(config.llvm_tools_dir, "spirv-as")))

clang/test/lit.site.cfg.py.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ config.llvm_external_lit = path(r"@LLVM_EXTERNAL_LIT@")
4343
config.standalone_build = @CLANG_BUILT_STANDALONE@
4444
config.ppc_linux_default_ieeelongdouble = @PPC_LINUX_DEFAULT_IEEELONGDOUBLE@
4545
config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@
46+
config.spirv_tools_tests = "@LLVM_INCLUDE_SPIRV_TOOLS_TESTS@"
4647
config.substitutions.append(("%llvm-version-major", "@LLVM_VERSION_MAJOR@"))
4748

4849
import lit.llvm

clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,15 @@ Expected<StringRef> linkDevice(ArrayRef<StringRef> InputFiles,
605605
}
606606
}
607607

608+
Error containerizeRawImage(std::unique_ptr<MemoryBuffer> &Img, OffloadKind Kind,
609+
const ArgList &Args) {
610+
llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ));
611+
if (Kind != OFK_OpenMP || !Triple.isSPIRV() ||
612+
Triple.getVendor() != llvm::Triple::Intel)
613+
return Error::success();
614+
return offloading::intel::containerizeOpenMPSPIRVImage(Img);
615+
}
616+
608617
Expected<StringRef> writeOffloadFile(const OffloadFile &File) {
609618
const OffloadBinary &Binary = *File.getBinary();
610619

@@ -957,6 +966,10 @@ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles(
957966
return createFileError(*OutputOrErr, EC);
958967
}
959968

969+
// Manually containerize offloading images not in ELF format.
970+
if (Error E = containerizeRawImage(*FileOrErr, Kind, LinkerArgs))
971+
return E;
972+
960973
std::scoped_lock<decltype(ImageMtx)> Guard(ImageMtx);
961974
OffloadingImage TheImage{};
962975
TheImage.TheImageKind =

flang/test/Driver/linker-flags.f90

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
! BSD-F128NONE-NOT: FortranFloat128Math
4242
! BSD-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed"
4343
! BSD-SAME: -lFortranRuntime
44-
! BSD-SAME: -lFortranDecimal
4544
! BSD-SAME: -lexecinfo
4645

4746
! DARWIN-LABEL: "{{.*}}ld{{(\.exe)?}}"

llvm/include/llvm/Frontend/Offloading/Utility.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_FRONTEND_OFFLOADING_UTILITY_H
1111

1212
#include <cstdint>
13+
#include <memory>
1314

1415
#include "llvm/ADT/StringMap.h"
1516
#include "llvm/ADT/StringRef.h"
@@ -152,6 +153,12 @@ Error getAMDGPUMetaDataFromImage(MemoryBufferRef MemBuffer,
152153
StringMap<AMDGPUKernelMetaData> &KernelInfoMap,
153154
uint16_t &ELFABIVersion);
154155
} // namespace amdgpu
156+
157+
namespace intel {
158+
/// Containerizes an offloading binary into the ELF binary format expected by
159+
/// the Intel runtime offload plugin.
160+
Error containerizeOpenMPSPIRVImage(std::unique_ptr<MemoryBuffer> &Binary);
161+
} // namespace intel
155162
} // namespace offloading
156163
} // namespace llvm
157164

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23188,7 +23188,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
2318823188
auto *VecLoad = dyn_cast<LoadSDNode>(VecOp);
2318923189
if (VecLoad && VecLoad->isSimple()) {
2319023190
if (SDValue Scalarized = TLI.scalarizeExtractedVectorLoad(
23191-
ExtVT, SDLoc(N), VecVT, Index, VecLoad, DAG)) {
23191+
ScalarVT, SDLoc(N), VecVT, Index, VecLoad, DAG)) {
2319223192
++OpsNarrowed;
2319323193
return Scalarized;
2319423194
}

llvm/lib/Frontend/Offloading/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_llvm_component_library(LLVMFrontendOffloading
1212
Core
1313
BinaryFormat
1414
Object
15+
ObjectYAML
1516
Support
1617
TransformUtils
1718
TargetParser

llvm/lib/Frontend/Offloading/Utility.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "llvm/IR/GlobalVariable.h"
1616
#include "llvm/IR/Value.h"
1717
#include "llvm/Object/ELFObjectFile.h"
18+
#include "llvm/ObjectYAML/ELFYAML.h"
19+
#include "llvm/ObjectYAML/yaml2obj.h"
1820
#include "llvm/Support/MemoryBufferRef.h"
1921
#include "llvm/Transforms/Utils/ModuleUtils.h"
2022

@@ -374,3 +376,86 @@ Error llvm::offloading::amdgpu::getAMDGPUMetaDataFromImage(
374376
}
375377
return Error::success();
376378
}
379+
Error offloading::intel::containerizeOpenMPSPIRVImage(
380+
std::unique_ptr<MemoryBuffer> &Img) {
381+
constexpr char INTEL_ONEOMP_OFFLOAD_VERSION[] = "1.0";
382+
constexpr int NT_INTEL_ONEOMP_OFFLOAD_VERSION = 1;
383+
constexpr int NT_INTEL_ONEOMP_OFFLOAD_IMAGE_COUNT = 2;
384+
constexpr int NT_INTEL_ONEOMP_OFFLOAD_IMAGE_AUX = 3;
385+
386+
// Start creating notes for the ELF container.
387+
std::vector<ELFYAML::NoteEntry> Notes;
388+
std::string Version = toHex(INTEL_ONEOMP_OFFLOAD_VERSION);
389+
Notes.emplace_back(ELFYAML::NoteEntry{"INTELONEOMPOFFLOAD",
390+
yaml::BinaryRef(Version),
391+
NT_INTEL_ONEOMP_OFFLOAD_VERSION});
392+
393+
// The AuxInfo string will hold auxiliary information for the image.
394+
// ELFYAML::NoteEntry structures will hold references to the
395+
// string, so we have to make sure the string is valid.
396+
std::string AuxInfo;
397+
398+
// TODO: Pass compile/link opts
399+
StringRef CompileOpts = "";
400+
StringRef LinkOpts = "";
401+
402+
unsigned ImageFmt = 1; // SPIR-V format
403+
404+
AuxInfo = toHex((Twine(0) + Twine('\0') + Twine(ImageFmt) + Twine('\0') +
405+
CompileOpts + Twine('\0') + LinkOpts)
406+
.str());
407+
Notes.emplace_back(ELFYAML::NoteEntry{"INTELONEOMPOFFLOAD",
408+
yaml::BinaryRef(AuxInfo),
409+
NT_INTEL_ONEOMP_OFFLOAD_IMAGE_AUX});
410+
411+
std::string ImgCount = toHex(Twine(1).str()); // always one image per ELF
412+
Notes.emplace_back(ELFYAML::NoteEntry{"INTELONEOMPOFFLOAD",
413+
yaml::BinaryRef(ImgCount),
414+
NT_INTEL_ONEOMP_OFFLOAD_IMAGE_COUNT});
415+
416+
std::string YamlFile;
417+
llvm::raw_string_ostream YamlFileStream(YamlFile);
418+
419+
// Write the YAML template file.
420+
421+
// We use 64-bit little-endian ELF currently.
422+
ELFYAML::FileHeader Header{};
423+
Header.Class = ELF::ELFCLASS64;
424+
Header.Data = ELF::ELFDATA2LSB;
425+
Header.Type = ELF::ET_DYN;
426+
// Use an existing Intel machine type as there is not one specifically for
427+
// Intel GPUs.
428+
Header.Machine = ELF::EM_IA_64;
429+
430+
// Create a section with notes.
431+
ELFYAML::NoteSection Section{};
432+
Section.Type = ELF::SHT_NOTE;
433+
Section.AddressAlign = 0;
434+
Section.Name = ".note.inteloneompoffload";
435+
Section.Notes.emplace(std::move(Notes));
436+
437+
ELFYAML::Object Object{};
438+
Object.Header = Header;
439+
Object.Chunks.push_back(
440+
std::make_unique<ELFYAML::NoteSection>(std::move(Section)));
441+
442+
// Create the section that will hold the image
443+
ELFYAML::RawContentSection ImageSection{};
444+
ImageSection.Type = ELF::SHT_PROGBITS;
445+
ImageSection.AddressAlign = 0;
446+
std::string Name = "__openmp_offload_spirv_0";
447+
ImageSection.Name = Name;
448+
ImageSection.Content =
449+
llvm::yaml::BinaryRef(arrayRefFromStringRef(Img->getBuffer()));
450+
Object.Chunks.push_back(
451+
std::make_unique<ELFYAML::RawContentSection>(std::move(ImageSection)));
452+
Error Err = Error::success();
453+
llvm::yaml::yaml2elf(
454+
Object, YamlFileStream,
455+
[&Err](const Twine &Msg) { Err = createStringError(Msg); }, UINT64_MAX);
456+
if (Err)
457+
return Err;
458+
459+
Img = MemoryBuffer::getMemBufferCopy(YamlFile);
460+
return Error::success();
461+
}

0 commit comments

Comments
 (0)