forked from OSchip/llvm-project
179 lines
6.0 KiB
C++
179 lines
6.0 KiB
C++
//===- llvm/unittest/IR/OpenMPIRBuilderTest.cpp - OpenMPIRBuilder tests ---===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
|
|
#include "llvm/IR/BasicBlock.h"
|
|
#include "llvm/IR/DIBuilder.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Frontend/OpenMP/OMPConstants.h"
|
|
#include "llvm/IR/Verifier.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
using namespace omp;
|
|
using namespace types;
|
|
|
|
namespace {
|
|
|
|
class OpenMPIRBuilderTest : public testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
M.reset(new Module("MyModule", Ctx));
|
|
FunctionType *FTy =
|
|
FunctionType::get(Type::getVoidTy(Ctx), {Type::getInt32Ty(Ctx)},
|
|
/*isVarArg=*/false);
|
|
F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
|
|
BB = BasicBlock::Create(Ctx, "", F);
|
|
|
|
DIBuilder DIB(*M);
|
|
auto File = DIB.createFile("test.dbg", "/");
|
|
auto CU =
|
|
DIB.createCompileUnit(dwarf::DW_LANG_C, File, "llvm-C", true, "", 0);
|
|
auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
|
|
auto SP = DIB.createFunction(
|
|
CU, "foo", "", File, 1, Type, 1, DINode::FlagZero,
|
|
DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
|
|
F->setSubprogram(SP);
|
|
auto Scope = DIB.createLexicalBlockFile(SP, File, 0);
|
|
DIB.finalize();
|
|
DL = DebugLoc::get(3, 7, Scope);
|
|
}
|
|
|
|
void TearDown() override {
|
|
BB = nullptr;
|
|
M.reset();
|
|
uninitializeTypes();
|
|
}
|
|
|
|
LLVMContext Ctx;
|
|
std::unique_ptr<Module> M;
|
|
Function *F;
|
|
BasicBlock *BB;
|
|
DebugLoc DL;
|
|
};
|
|
|
|
TEST_F(OpenMPIRBuilderTest, CreateBarrier) {
|
|
OpenMPIRBuilder OMPBuilder(*M);
|
|
OMPBuilder.initialize();
|
|
|
|
IRBuilder<> Builder(BB);
|
|
|
|
OMPBuilder.CreateBarrier({IRBuilder<>::InsertPoint()}, OMPD_for);
|
|
EXPECT_TRUE(M->global_empty());
|
|
EXPECT_EQ(M->size(), 1U);
|
|
EXPECT_EQ(F->size(), 1U);
|
|
EXPECT_EQ(BB->size(), 0U);
|
|
|
|
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
|
|
OMPBuilder.CreateBarrier(Loc, OMPD_for);
|
|
EXPECT_FALSE(M->global_empty());
|
|
EXPECT_EQ(M->size(), 3U);
|
|
EXPECT_EQ(F->size(), 1U);
|
|
EXPECT_EQ(BB->size(), 2U);
|
|
|
|
CallInst *GTID = dyn_cast<CallInst>(&BB->front());
|
|
EXPECT_NE(GTID, nullptr);
|
|
EXPECT_EQ(GTID->getNumArgOperands(), 1U);
|
|
EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
|
|
EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
|
|
EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
|
|
|
|
CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
|
|
EXPECT_NE(Barrier, nullptr);
|
|
EXPECT_EQ(Barrier->getNumArgOperands(), 2U);
|
|
EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_barrier");
|
|
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
|
|
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
|
|
|
|
EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
|
|
|
|
Builder.CreateUnreachable();
|
|
EXPECT_FALSE(verifyModule(*M));
|
|
}
|
|
|
|
TEST_F(OpenMPIRBuilderTest, CreateCancelBarrier) {
|
|
OpenMPIRBuilder OMPBuilder(*M);
|
|
OMPBuilder.initialize();
|
|
|
|
BasicBlock *CBB = BasicBlock::Create(Ctx, "", F);
|
|
new UnreachableInst(Ctx, CBB);
|
|
OMPBuilder.setCancellationBlock(CBB);
|
|
|
|
IRBuilder<> Builder(BB);
|
|
|
|
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP()});
|
|
auto NewIP = OMPBuilder.CreateBarrier(Loc, OMPD_for);
|
|
Builder.restoreIP(NewIP);
|
|
EXPECT_FALSE(M->global_empty());
|
|
EXPECT_EQ(M->size(), 3U);
|
|
EXPECT_EQ(F->size(), 3U);
|
|
EXPECT_EQ(BB->size(), 4U);
|
|
|
|
CallInst *GTID = dyn_cast<CallInst>(&BB->front());
|
|
EXPECT_NE(GTID, nullptr);
|
|
EXPECT_EQ(GTID->getNumArgOperands(), 1U);
|
|
EXPECT_EQ(GTID->getCalledFunction()->getName(), "__kmpc_global_thread_num");
|
|
EXPECT_FALSE(GTID->getCalledFunction()->doesNotAccessMemory());
|
|
EXPECT_FALSE(GTID->getCalledFunction()->doesNotFreeMemory());
|
|
|
|
CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
|
|
EXPECT_NE(Barrier, nullptr);
|
|
EXPECT_EQ(Barrier->getNumArgOperands(), 2U);
|
|
EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier");
|
|
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
|
|
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
|
|
EXPECT_EQ(Barrier->getNumUses(), 1U);
|
|
Instruction *BarrierBBTI = Barrier->getParent()->getTerminator();
|
|
EXPECT_EQ(BarrierBBTI->getNumSuccessors(), 2U);
|
|
EXPECT_EQ(BarrierBBTI->getSuccessor(0), NewIP.getBlock());
|
|
EXPECT_EQ(BarrierBBTI->getSuccessor(1), CBB);
|
|
|
|
EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
|
|
|
|
Builder.CreateUnreachable();
|
|
EXPECT_FALSE(verifyModule(*M));
|
|
}
|
|
|
|
TEST_F(OpenMPIRBuilderTest, DbgLoc) {
|
|
OpenMPIRBuilder OMPBuilder(*M);
|
|
OMPBuilder.initialize();
|
|
F->setName("func");
|
|
|
|
IRBuilder<> Builder(BB);
|
|
|
|
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
|
|
OMPBuilder.CreateBarrier(Loc, OMPD_for);
|
|
CallInst *GTID = dyn_cast<CallInst>(&BB->front());
|
|
CallInst *Barrier = dyn_cast<CallInst>(GTID->getNextNode());
|
|
EXPECT_EQ(GTID->getDebugLoc(), DL);
|
|
EXPECT_EQ(Barrier->getDebugLoc(), DL);
|
|
EXPECT_TRUE(isa<GlobalVariable>(Barrier->getOperand(0)));
|
|
if (!isa<GlobalVariable>(Barrier->getOperand(0)))
|
|
return;
|
|
GlobalVariable *Ident = cast<GlobalVariable>(Barrier->getOperand(0));
|
|
EXPECT_TRUE(Ident->hasInitializer());
|
|
if (!Ident->hasInitializer())
|
|
return;
|
|
Constant *Initializer = Ident->getInitializer();
|
|
EXPECT_TRUE(
|
|
isa<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts()));
|
|
GlobalVariable *SrcStrGlob =
|
|
cast<GlobalVariable>(Initializer->getOperand(4)->stripPointerCasts());
|
|
if (!SrcStrGlob)
|
|
return;
|
|
EXPECT_TRUE(isa<ConstantDataArray>(SrcStrGlob->getInitializer()));
|
|
ConstantDataArray *SrcSrc =
|
|
dyn_cast<ConstantDataArray>(SrcStrGlob->getInitializer());
|
|
if (!SrcSrc)
|
|
return;
|
|
EXPECT_EQ(SrcSrc->getAsCString(), ";test.dbg;foo;3;7;;");
|
|
}
|
|
} // namespace
|