diff --git a/docs/LangRef.html b/docs/LangRef.html index 23c07c70761..af0e5640c5b 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -2176,13 +2176,11 @@ has undefined behavior.

Blocks
-

blockaddress(@function, %block)
- blockaddress(@function, null)

+

blockaddress(@function, %block)

The 'blockaddress' constant computes the address of the specified basic block in the specified function, and always has an i8* type. Taking - the address of the entry block is illegal. The BasicBlock operand may also - be null.

+ the address of the entry block is illegal.

This value only has defined behavior when used as an operand to the 'indirectbr' instruction or for comparisons diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index f493ee68ffe..99928d9b855 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -567,10 +567,6 @@ public: DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); Function *getFunction() const { return (Function*)Op<0>().get(); } - - /// getBasicBlock - This returns the block associated with this BlockAddress. - /// Note that this can return null if the block this originally referred to - /// was deleted. BasicBlock *getBasicBlock() const { return (BasicBlock*)Op<1>().get(); } /// isNullValue - Return true if this is the value that would be returned by diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 9dbd78c558e..07bf261573c 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -123,25 +123,20 @@ bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, // Loop over all the references, resolving them. for (unsigned i = 0, e = Refs.size(); i != e; ++i) { BasicBlock *Res; - if (Refs[i].first.Kind == ValID::t_Null) - Res = 0; - else if (PFS) { + if (PFS) { if (Refs[i].first.Kind == ValID::t_LocalName) Res = PFS->GetBB(Refs[i].first.StrVal, Refs[i].first.Loc); - else { - assert(Refs[i].first.Kind == ValID::t_LocalID); + else Res = PFS->GetBB(Refs[i].first.UIntVal, Refs[i].first.Loc); - } } else if (Refs[i].first.Kind == ValID::t_LocalID) { return Error(Refs[i].first.Loc, "cannot take address of numeric label after it the function is defined"); } else { - assert(Refs[i].first.Kind == ValID::t_LocalName); Res = dyn_cast_or_null( TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal)); } - if (Res == 0 && Refs[i].first.Kind != ValID::t_Null) + if (Res == 0) return Error(Refs[i].first.Loc, "referenced value is not a basic block"); @@ -2060,11 +2055,10 @@ bool LLParser::ParseValID(ValID &ID) { ParseValID(Label) || ParseToken(lltok::rparen, "expected ')' in block address expression")) return true; - + if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName) return Error(Fn.Loc, "expected function name in blockaddress"); - if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName && - Label.Kind != ValID::t_Null) + if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName) return Error(Label.Loc, "expected basic block name in blockaddress"); // Make a global variable as a placeholder for this reference. diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 749f16f7f3b..68527e3d474 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2274,12 +2274,11 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { std::vector &RefList = BAFRI->second; for (unsigned i = 0, e = RefList.size(); i != e; ++i) { unsigned BlockIdx = RefList[i].first; - if (BlockIdx > FunctionBBs.size()) + if (BlockIdx >= FunctionBBs.size()) return Error("Invalid blockaddress block #"); GlobalVariable *FwdRef = RefList[i].second; - BasicBlock *BB = BlockIdx == 0 ? 0 : FunctionBBs[BlockIdx-1]; - FwdRef->replaceAllUsesWith(BlockAddress::get(F, BB)); + FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx])); FwdRef->eraseFromParent(); } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index e32977db414..af0b8acd44c 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -854,8 +854,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, break; } } else if (const BlockAddress *BA = dyn_cast(C)) { - assert((!BA->getBasicBlock() || - BA->getFunction() == BA->getBasicBlock()->getParent()) && + assert(BA->getFunction() == BA->getBasicBlock()->getParent() && "Malformed blockaddress"); Code = bitc::CST_CODE_BLOCKADDRESS; Record.push_back(VE.getTypeID(BA->getFunction()->getType())); diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 92a9bab4e76..d840d4ae9fe 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -265,8 +265,6 @@ void ValueEnumerator::EnumerateValue(const Value *V) { // Do not enumerate the initializers for an array of simple characters. // The initializers just polute the value table, and we emit the strings // specially. - } else if (isa(C)) { - // Don't enumerate function or block. } else if (C->getNumOperands()) { // If a constant has operands, enumerate them. This makes sure that if a // constant has uses (for example an array of const ints), that they are @@ -278,7 +276,8 @@ void ValueEnumerator::EnumerateValue(const Value *V) { // graph that don't go through a global variable. for (User::const_op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I) - EnumerateValue(*I); + if (!isa(*I)) // Don't enumerate BB operand to BlockAddress. + EnumerateValue(*I); // Finally, add the value. Doing this could make the ValueID reference be // dangling, don't reuse it. @@ -418,10 +417,9 @@ static void IncorporateFunctionInfoGlobalBBIDs(const Function *F, /// specified basic block. This is relatively expensive information, so it /// should only be used by rare constructs such as address-of-label. unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const { - if (BB == 0) return 0; unsigned &Idx = GlobalBasicBlockIDs[BB]; if (Idx != 0) - return Idx; + return Idx-1; IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs); return getGlobalBasicBlockID(BB); diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 94951002b46..49e9683a556 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -2345,7 +2345,8 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, Value *Val = getVal(Values, IBI->getAddress())->stripPointerCasts(); if (BlockAddress *BA = dyn_cast(Val)) NewBB = BA->getBasicBlock(); - if (NewBB == 0) return false; // Cannot determine. + else + return false; // Cannot determine. } else if (ReturnInst *RI = dyn_cast(CurInst)) { if (RI->getNumOperands()) RetVal = getVal(Values, RI->getOperand(0)); diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 7929eb9ac2b..39331d78169 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -113,13 +113,8 @@ Value *llvm::MapValue(const Value *V, ValueMapTy &VM) { if (BlockAddress *BA = dyn_cast(C)) { Function *F = cast(MapValue(BA->getFunction(), VM)); - BasicBlock *BB = 0; - if (BA->getBasicBlock()) { - BB = cast_or_null(MapValue(BA->getBasicBlock(),VM)); - BB = BB ? BB : BA->getBasicBlock(); - } - - return VM[V] = BlockAddress::get(F, BB); + BasicBlock *BB = cast_or_null(MapValue(BA->getBasicBlock(),VM)); + return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock()); } llvm_unreachable("Unknown type of constant!"); diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index df1d19b0fcf..9a803a16628 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1065,10 +1065,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV, Out << "blockaddress("; WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine); Out << ", "; - if (BA->getBasicBlock()) - WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine); - else - Out << "null"; + WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine); Out << ")"; return; } diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index c609ef85ebd..23d0557dc74 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -63,13 +63,15 @@ BasicBlock::~BasicBlock() { // hanging off the block, or an undefined use of the block (source code // expecting the address of a label to keep the block alive even though there // is no indirect branch). Handle these cases by zapping the BlockAddress - // nodes, replacing them with BlockAddress(F, NULL). There are no other - // possible uses at this point. + // nodes. There are no other possible uses at this point. if (hasAddressTaken()) { assert(!use_empty() && "There should be at least one blockaddress!"); + Constant *Replacement = + ConstantInt::get(llvm::Type::getInt32Ty(getContext()), 1); while (!use_empty()) { BlockAddress *BA = cast(use_back()); - BA->replaceAllUsesWith(BlockAddress::get(BA->getFunction(), 0)); + BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement, + BA->getType())); BA->destroyConstant(); } } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index e0adf9d2fd5..2d3d71b6863 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -1045,7 +1045,7 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) &Op<0>(), 2) { Op<0>() = F; Op<1>() = BB; - if (BB) BB->AdjustBlockAddressRefCount(1); + BB->AdjustBlockAddressRefCount(1); } @@ -1054,8 +1054,7 @@ BlockAddress::BlockAddress(Function *F, BasicBlock *BB) void BlockAddress::destroyConstant() { getFunction()->getType()->getContext().pImpl ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock())); - if (BasicBlock *BB = getBasicBlock()) - BB->AdjustBlockAddressRefCount(-1); + getBasicBlock()->AdjustBlockAddressRefCount(-1); destroyConstantImpl(); }