Lower static global into allocas. (#299)

This commit is contained in:
Xiang Li 2017-05-17 10:45:48 -07:00 коммит произвёл GitHub
Родитель 5e70ea6d8f
Коммит e5ef77995c
3 изменённых файлов: 76 добавлений и 3 удалений

Просмотреть файл

@ -3527,7 +3527,7 @@ void PointerStatus::analyzePointer(const Value *V, PointerStatus &PS,
if (const Instruction *I = dyn_cast<Instruction>(U)) {
const Function *F = I->getParent()->getParent();
if (!PS.AccessingFunction) {
F = PS.AccessingFunction;
PS.AccessingFunction = F;
} else {
if (F != PS.AccessingFunction)
PS.HasMultipleAccessingFunctions = true;
@ -3943,6 +3943,24 @@ public:
}
}
// Lower static global into allocas.
staticGVs.clear();
for (GlobalVariable &GV : M.globals()) {
bool isStaticGlobal =
HLModule::IsStaticGlobal(&GV) &&
GV.getType()->getAddressSpace() == DXIL::kDefaultAddrSpace;
bool noInitializer =
!GV.hasInitializer() || isa<UndefValue>(GV.getInitializer());
if (isStaticGlobal && noInitializer) {
staticGVs.emplace_back(&GV);
}
}
const DataLayout &DL = M.getDataLayout();
for (GlobalVariable *GV : staticGVs) {
lowerStaticGlobalIntoAlloca(GV, DL);
}
return true;
}
@ -3977,6 +3995,7 @@ private:
unsigned startArgIndex, llvm::StringMap<Type *> &semanticTypeMap);
bool hasDynamicVectorIndexing(Value *V);
void flattenGlobal(GlobalVariable *GV);
void lowerStaticGlobalIntoAlloca(GlobalVariable *GV, const DataLayout &DL);
/// DeadInsts - Keep track of instructions we have made dead, so that
/// we can remove them after we are done working.
SmallVector<Value *, 32> DeadInsts;
@ -4064,8 +4083,6 @@ void SROA_Parameter_HLSL::flattenGlobal(GlobalVariable *GV) {
while (!WorkList.empty()) {
GlobalVariable *EltGV = cast<GlobalVariable>(WorkList.front());
WorkList.pop_front();
// Flat Global vector if no dynamic vector indexing.
bool bFlatVector = !hasDynamicVectorIndexing(EltGV);
const bool bAllowReplace = true;
if (SROA_Helper::LowerMemcpy(EltGV, /*annoation*/ nullptr, dxilTypeSys, DL,
@ -4073,6 +4090,8 @@ void SROA_Parameter_HLSL::flattenGlobal(GlobalVariable *GV) {
continue;
}
// Flat Global vector if no dynamic vector indexing.
bool bFlatVector = !hasDynamicVectorIndexing(EltGV);
std::vector<Value *> Elts;
bool SROAed = SROA_Helper::DoScalarReplacement(
EltGV, Elts, Builder, bFlatVector,
@ -4118,6 +4137,23 @@ void SROA_Parameter_HLSL::flattenGlobal(GlobalVariable *GV) {
}
}
void SROA_Parameter_HLSL::lowerStaticGlobalIntoAlloca(GlobalVariable *GV, const DataLayout &DL) {
DxilTypeSystem &typeSys = m_pHLModule->GetTypeSystem();
unsigned size = DL.getTypeAllocSize(GV->getType()->getElementType());
PointerStatus PS(size);
GV->removeDeadConstantUsers();
PS.analyzePointer(GV, PS, typeSys, /*bStructElt*/false);
// Make sure GV only used in one function.
if (PS.HasMultipleAccessingFunctions)
return;
Function *F = const_cast<Function*>(PS.AccessingFunction);
IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt());
AllocaInst *AI = Builder.CreateAlloca(GV->getType()->getElementType());
ReplaceConstantWithInst(GV, AI, Builder);
GV->eraseFromParent();
}
static DxilFieldAnnotation &GetEltAnnotation(Type *Ty, unsigned idx, DxilFieldAnnotation &annotation, DxilTypeSystem &dxilTypeSys) {
while (Ty->isArrayTy())
Ty = Ty->getArrayElementType();

Просмотреть файл

@ -0,0 +1,32 @@
// RUN: %dxc -E not_main -T ps_6_0 %s | FileCheck %s
// Make sure no load and store
// CHECK-NOT: store float
// CHECK-NOT: = load
cbuffer T
{
float4 a;
float4 b;
}
static struct X
{
float4 a;
float4 b;
} ST = { a, b};
uint t;
// Not use main as entry name to disable GlobalOpt.
float4 not_main() : SV_Target
{
float tmp = 0;
// Make big number of instructions to disable gvn.
[unroll]
for (uint i=0;i<100;i++)
tmp += sin(t+i);
return tmp + i + sin(ST.a) + ST.b;
}

Просмотреть файл

@ -392,6 +392,7 @@ public:
TEST_METHOD(CodeGenCast7)
TEST_METHOD(CodeGenCbuf_init_static)
TEST_METHOD(CodeGenCbufferCopy)
TEST_METHOD(CodeGenCbufferCopy1)
TEST_METHOD(CodeGenCbufferCopy2)
TEST_METHOD(CodeGenCbufferCopy3)
TEST_METHOD(CodeGenCbufferCopy4)
@ -2314,6 +2315,10 @@ TEST_F(CompilerTest, CodeGenCbufferCopy) {
CodeGenTestCheck(L"..\\CodeGenHLSL\\cbuffer_copy.hlsl");
}
TEST_F(CompilerTest, CodeGenCbufferCopy1) {
CodeGenTestCheck(L"..\\CodeGenHLSL\\cbuffer_copy1.hlsl");
}
TEST_F(CompilerTest, CodeGenCbufferCopy2) {
CodeGenTestCheck(L"..\\CodeGenHLSL\\cbuffer_copy2.hlsl");
}