1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-01 08:23:21 +01:00
llvm-mirror/unittests/Analysis/ScalarEvolutionTest.cpp
Dan Gohman 68ac0492a4 Make SCEVUnknown a CallbackVH, so that it can be notified directly
of Value deletions and RAUWs, instead of relying on ScalarEvolution's
Scalars map being notified, as that's complicated at best, and
insufficient in general.

This means SCEVUnknown needs a non-trivial destructor, so introduce
a mechanism to allow ScalarEvolution to locate all the SCEVUnknowns.

llvm-svn: 110086
2010-08-02 23:49:30 +00:00

83 lines
2.9 KiB
C++

//===- ScalarEvolutionsTest.cpp - ScalarEvolution unit tests --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <llvm/Analysis/ScalarEvolutionExpressions.h>
#include <llvm/GlobalVariable.h>
#include <llvm/Constants.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/PassManager.h>
#include "gtest/gtest.h"
namespace llvm {
namespace {
TEST(ScalarEvolutionsTest, SCEVUnknownRAUW) {
LLVMContext Context;
Module M("world", Context);
const FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
std::vector<const Type *>(), false);
Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
ReturnInst::Create(Context, 0, BB);
const Type *Ty = Type::getInt1Ty(Context);
Constant *Init = Constant::getNullValue(Ty);
Value *V0 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V0");
Value *V1 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V1");
Value *V2 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V2");
// Create a ScalarEvolution and "run" it so that it gets initialized.
PassManager PM;
ScalarEvolution &SE = *new ScalarEvolution();
PM.add(&SE);
PM.run(M);
const SCEV *S0 = SE.getSCEV(V0);
const SCEV *S1 = SE.getSCEV(V1);
const SCEV *S2 = SE.getSCEV(V2);
const SCEV *P0 = SE.getAddExpr(S0, S0);
const SCEV *P1 = SE.getAddExpr(S1, S1);
const SCEV *P2 = SE.getAddExpr(S2, S2);
const SCEVMulExpr *M0 = cast<SCEVMulExpr>(P0);
const SCEVMulExpr *M1 = cast<SCEVMulExpr>(P1);
const SCEVMulExpr *M2 = cast<SCEVMulExpr>(P2);
EXPECT_EQ(cast<SCEVConstant>(M0->getOperand(0))->getValue()->getZExtValue(),
2u);
EXPECT_EQ(cast<SCEVConstant>(M1->getOperand(0))->getValue()->getZExtValue(),
2u);
EXPECT_EQ(cast<SCEVConstant>(M2->getOperand(0))->getValue()->getZExtValue(),
2u);
// Before the RAUWs, these are all pointing to separate values.
EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V1);
EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V2);
// Do some RAUWs.
V2->replaceAllUsesWith(V1);
V1->replaceAllUsesWith(V0);
// After the RAUWs, these should all be pointing to V0.
EXPECT_EQ(cast<SCEVUnknown>(M0->getOperand(1))->getValue(), V0);
EXPECT_EQ(cast<SCEVUnknown>(M1->getOperand(1))->getValue(), V0);
EXPECT_EQ(cast<SCEVUnknown>(M2->getOperand(1))->getValue(), V0);
// Manually clean up, since we allocated new SCEV objects after the
// pass was finished.
SE.releaseMemory();
}
} // end anonymous namespace
} // end namespace llvm