10f152a55SDhruv Chawla //===- InferAlignment.cpp -------------------------------------------------===// 20f152a55SDhruv Chawla // 30f152a55SDhruv Chawla // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40f152a55SDhruv Chawla // See https://llvm.org/LICENSE.txt for license information. 50f152a55SDhruv Chawla // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60f152a55SDhruv Chawla // 70f152a55SDhruv Chawla //===----------------------------------------------------------------------===// 80f152a55SDhruv Chawla // 90f152a55SDhruv Chawla // Infer alignment for load, stores and other memory operations based on 100f152a55SDhruv Chawla // trailing zero known bits information. 110f152a55SDhruv Chawla // 120f152a55SDhruv Chawla //===----------------------------------------------------------------------===// 130f152a55SDhruv Chawla 140f152a55SDhruv Chawla #include "llvm/Transforms/Scalar/InferAlignment.h" 150f152a55SDhruv Chawla #include "llvm/Analysis/AssumptionCache.h" 160f152a55SDhruv Chawla #include "llvm/Analysis/ValueTracking.h" 170f152a55SDhruv Chawla #include "llvm/IR/Instructions.h" 180f152a55SDhruv Chawla #include "llvm/Support/KnownBits.h" 190f152a55SDhruv Chawla #include "llvm/Transforms/Scalar.h" 200f152a55SDhruv Chawla #include "llvm/Transforms/Utils/Local.h" 210f152a55SDhruv Chawla 220f152a55SDhruv Chawla using namespace llvm; 230f152a55SDhruv Chawla 240f152a55SDhruv Chawla static bool tryToImproveAlign( 250f152a55SDhruv Chawla const DataLayout &DL, Instruction *I, 260f152a55SDhruv Chawla function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn) { 27*8c60efe9Shanbeom 28*8c60efe9Shanbeom if (auto *PtrOp = getLoadStorePointerOperand(I)) { 29*8c60efe9Shanbeom Align OldAlign = getLoadStoreAlignment(I); 30*8c60efe9Shanbeom Align PrefAlign = DL.getPrefTypeAlign(getLoadStoreType(I)); 31*8c60efe9Shanbeom 32*8c60efe9Shanbeom Align NewAlign = Fn(PtrOp, OldAlign, PrefAlign); 330f152a55SDhruv Chawla if (NewAlign > OldAlign) { 34*8c60efe9Shanbeom setLoadStoreAlignment(I, NewAlign); 350f152a55SDhruv Chawla return true; 360f152a55SDhruv Chawla } 370f152a55SDhruv Chawla } 380f152a55SDhruv Chawla // TODO: Also handle memory intrinsics. 390f152a55SDhruv Chawla return false; 400f152a55SDhruv Chawla } 410f152a55SDhruv Chawla 420f152a55SDhruv Chawla bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) { 439df71d76SNikita Popov const DataLayout &DL = F.getDataLayout(); 440f152a55SDhruv Chawla bool Changed = false; 450f152a55SDhruv Chawla 460f152a55SDhruv Chawla // Enforce preferred type alignment if possible. We do this as a separate 470f152a55SDhruv Chawla // pass first, because it may improve the alignments we infer below. 480f152a55SDhruv Chawla for (BasicBlock &BB : F) { 490f152a55SDhruv Chawla for (Instruction &I : BB) { 500f152a55SDhruv Chawla Changed |= tryToImproveAlign( 510f152a55SDhruv Chawla DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) { 520f152a55SDhruv Chawla if (PrefAlign > OldAlign) 530f152a55SDhruv Chawla return std::max(OldAlign, 540f152a55SDhruv Chawla tryEnforceAlignment(PtrOp, PrefAlign, DL)); 550f152a55SDhruv Chawla return OldAlign; 560f152a55SDhruv Chawla }); 570f152a55SDhruv Chawla } 580f152a55SDhruv Chawla } 590f152a55SDhruv Chawla 600f152a55SDhruv Chawla // Compute alignment from known bits. 610f152a55SDhruv Chawla for (BasicBlock &BB : F) { 620f152a55SDhruv Chawla for (Instruction &I : BB) { 630f152a55SDhruv Chawla Changed |= tryToImproveAlign( 640f152a55SDhruv Chawla DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) { 650f152a55SDhruv Chawla KnownBits Known = computeKnownBits(PtrOp, DL, 0, &AC, &I, &DT); 660f152a55SDhruv Chawla unsigned TrailZ = std::min(Known.countMinTrailingZeros(), 670f152a55SDhruv Chawla +Value::MaxAlignmentExponent); 680f152a55SDhruv Chawla return Align(1ull << std::min(Known.getBitWidth() - 1, TrailZ)); 690f152a55SDhruv Chawla }); 700f152a55SDhruv Chawla } 710f152a55SDhruv Chawla } 720f152a55SDhruv Chawla 730f152a55SDhruv Chawla return Changed; 740f152a55SDhruv Chawla } 750f152a55SDhruv Chawla 760f152a55SDhruv Chawla PreservedAnalyses InferAlignmentPass::run(Function &F, 770f152a55SDhruv Chawla FunctionAnalysisManager &AM) { 780f152a55SDhruv Chawla AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F); 790f152a55SDhruv Chawla DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F); 800f152a55SDhruv Chawla inferAlignment(F, AC, DT); 810f152a55SDhruv Chawla // Changes to alignment shouldn't invalidated analyses. 820f152a55SDhruv Chawla return PreservedAnalyses::all(); 830f152a55SDhruv Chawla } 84