void FunctionSignatureSpecializationMangler::mangleConstantProp(LiteralInst *LI) { Mangler &M = getMangler(); llvm::raw_ostream &os = getBuffer(); // Append the prefix for constant propagation 'cp'. os << "cp"; // Then append the unique identifier of our literal. switch (LI->getKind()) { default: llvm_unreachable("unknown literal"); case ValueKind::FunctionRefInst: { SILFunction *F = cast<FunctionRefInst>(LI)->getReferencedFunction(); os << "fr"; M.mangleIdentifier(F->getName()); break; } case ValueKind::GlobalAddrInst: { SILGlobalVariable *G = cast<GlobalAddrInst>(LI)->getReferencedGlobal(); os << "g"; M.mangleIdentifier(G->getName()); break; } case ValueKind::IntegerLiteralInst: { APInt apint = cast<IntegerLiteralInst>(LI)->getValue(); os << "i" << apint; break; } case ValueKind::FloatLiteralInst: { APInt apint = cast<FloatLiteralInst>(LI)->getBits(); os << "fl" << apint; break; } case ValueKind::StringLiteralInst: { StringLiteralInst *SLI = cast<StringLiteralInst>(LI); StringRef V = SLI->getValue(); assert(V.size() <= 32 && "Can not encode string of length > 32"); llvm::SmallString<33> Str; Str += "u"; Str += V; os << "se" << unsigned(SLI->getEncoding()) << "v"; M.mangleIdentifier(Str); break; } } }
/// We analyze the body of globalinit_func to see if it can be statically /// initialized. If yes, we set the initial value of the SILGlobalVariable and /// remove the "once" call to globalinit_func from the addressor. void SILGlobalOpt::optimizeInitializer(SILFunction *AddrF, GlobalInitCalls &Calls) { if (UnhandledOnceCallee) return; // Find the initializer and the SILGlobalVariable. BuiltinInst *CallToOnce; // If the addressor contains a single "once" call, it calls globalinit_func, // and the globalinit_func is called by "once" from a single location, // continue; otherwise bail. auto *InitF = findInitializer(Module, AddrF, CallToOnce); if (!InitF || !InitF->getName().startswith("globalinit_") || InitializerCount[InitF] > 1) return; // If the globalinit_func is trivial, continue; otherwise bail. SingleValueInstruction *InitVal; SILGlobalVariable *SILG = getVariableOfStaticInitializer(InitF, InitVal); if (!SILG) return; LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: use static initializer for " << SILG->getName() << '\n'); // Remove "once" call from the addressor. if (!isAssignedOnlyOnceInInitializer(SILG) || !SILG->getDecl()) { removeToken(CallToOnce->getOperand(0)); CallToOnce->eraseFromParent(); StaticInitCloner::appendToInitializer(SILG, InitVal); HasChanged = true; return; } replaceLoadsByKnownValue(CallToOnce, AddrF, InitF, SILG, InitVal, Calls); HasChanged = true; }